Skip to content

Commit f74cb1f

Browse files
authored
Merge pull request #91 from thenetrunna/master
netlibc: add example and new mem module
2 parents 8b68596 + 3daa32e commit f74cb1f

File tree

14 files changed

+345
-16
lines changed

14 files changed

+345
-16
lines changed

netlibc/examples/assert.c

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "../include/netlibc/assert.h"
2+
3+
int main() {
4+
ASSERT_TRUE(true, "assert should pass");
5+
6+
ASSERT_FALSE(false, "assert should pass");
7+
8+
ASSERT_TRUE(false, NULL);
9+
10+
// ASSERT_TRUE(1 > 0, "assert should fail");
11+
12+
return 0;
13+
}

netlibc/examples/log.c

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "../include/netlibc/assert.h"
2+
#include "../include/netlibc/log.h"
3+
4+
int main() {
5+
LOG(INFO, "Hello world");
6+
7+
return 0;
8+
}

netlibc/examples/mem.c

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// #define MEMDEBUG
2+
#include "../include/netlibc/mem.h"
3+
#include "../include/netlibc.h"
4+
5+
int main() {
6+
NETLIBC_INIT(MEM_DEBUG_ENABLED);
7+
8+
void *allocated = nmalloc(100);
9+
10+
void *allocated2 = nmalloc(100);
11+
12+
void *allocated3 = nmalloc(100);
13+
14+
nfree(allocated);
15+
nfree(allocated2);
16+
// nfree(allocated3);
17+
18+
return 0;
19+
}

netlibc/include/netlibc.h

+36-1
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,39 @@ u64 get_timestamp_ms();
5656

5757
u64 get_timestamp_s();
5858

59-
#endif
59+
typedef struct {
60+
void *address;
61+
u64 size;
62+
bool freed;
63+
64+
char *file;
65+
u64 line;
66+
} mem_alloc_info_t;
67+
68+
typedef struct {
69+
bool mem_debug_enabled;
70+
71+
mem_alloc_info_t *mem_allocations;
72+
u64 mem_allocations_count;
73+
u64 mem_free_count;
74+
} netlibc_ctx_t;
75+
76+
extern netlibc_ctx_t *__netlibc_ctx;
77+
78+
void __netlibc_ctx_init(bool mem_debug_enabled);
79+
80+
void __netlibc_ctx_exit();
81+
82+
#define MEM_DEBUG_ENABLED true
83+
#define MEM_DEBUG_DISABLED false
84+
85+
#define NETLIBC_INIT(mem_debug_enabled) __netlibc_ctx_init(mem_debug_enabled)
86+
87+
#define ASSERT_NETLIBC_INIT() \
88+
do { \
89+
if (__netlibc_ctx == NULL) { \
90+
PANIC("NETLIBC NOT INITIALIZED"); \
91+
} \
92+
} while (0)
93+
94+
#endif

netlibc/include/netlibc/assert.h

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef NETLIBC_ASSERT_H
2+
#define NETLIBC_ASSERT_H
3+
4+
#include "../netlibc.h"
5+
6+
void __netlibc_assert_true(bool condition, char *error_message, char *file,
7+
int line);
8+
9+
void __netlibc_assert_false(bool condition, char *error_message, char *file,
10+
int line);
11+
12+
#ifndef NDEBUG
13+
14+
#define ASSERT_TRUE(condition, message) \
15+
__netlibc_assert_true(condition, message, __FILE__, __LINE__)
16+
17+
#define ASSERT_FALSE(condition, message) \
18+
__netlibc_assert_false(condition, message, __FILE__, __LINE__)
19+
20+
#endif
21+
22+
#ifdef NDEBUG
23+
#define ASSERT_TRUE(condition, message)
24+
#define ASSERT_FALSE(condition, message)
25+
#endif
26+
27+
#endif

netlibc/include/netlibc/log.h

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ typedef enum {
99
ERROR,
1010
} log_level_t;
1111

12+
#define RED_COLOR 227, 61, 45
13+
#define YELLOW_COLOR 227, 224, 45
14+
1215
#define EXIT(...) __netlibc_exit(__FILE__, __LINE__, __VA_ARGS__)
1316

1417
#define PANIC(...) __netlibc_panic(__FILE__, __LINE__, __VA_ARGS__)
@@ -24,4 +27,8 @@ void __netlibc_panic(const char *file, int line, const char *format, ...);
2427
void __netlibc_exit(const char *file, int line, int status, const char *format,
2528
...);
2629

30+
void set_color_rgb(u8 r, u8 g, u8 b);
31+
32+
void reset_color();
33+
2734
#endif

netlibc/include/netlibc/mem.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef NETLIBC_MEM_H
2+
#define NETLIBC_MEM_H
3+
4+
#include "../netlibc.h"
5+
6+
void *__netlibc_malloc(size_t size, char *file, u64 line);
7+
8+
void *__netlibc_realloc(void *pre_allocated, size_t new_size);
9+
10+
void *__netlibc_calloc(u64 count, size_t size);
11+
12+
void __netlibc_free(void *allocated, char *file, u64 line);
13+
14+
#define nmalloc(size) __netlibc_malloc(size, __FILE__, __LINE__);
15+
16+
#define ncalloc(count, size) __netlibc_calloc(count, size);
17+
18+
#define nrealloc(pre_allocated, new_size) \
19+
__netlibc_malloc(pre_allocated, new_size);
20+
21+
#define nfree(allocated) __netlibc_free(allocated, __FILE__, __LINE__);
22+
23+
#endif

netlibc/makefile

+3-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

netlibc/src/assert.c

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**** assert.c ****
2+
*
3+
* Copyright (c) 2023 ShogAI - https://shog.ai
4+
*
5+
* Part of netlibc, under the MIT License.
6+
* See LICENSE file for license information.
7+
* SPDX-License-Identifier: MIT
8+
*
9+
****/
10+
11+
#include "../include/netlibc/assert.h"
12+
#include "../include/netlibc/log.h"
13+
14+
#include <stdlib.h>
15+
16+
void __assert_fail(char *prefix, char *error_message, char *file, int line) {
17+
set_color_rgb(RED_COLOR);
18+
printf("[PANIC] %s FAILED ", prefix);
19+
20+
fprintf(stdout, "at %s:%d: ", file, line);
21+
22+
reset_color();
23+
24+
if (error_message != NULL) {
25+
printf("%s", error_message);
26+
}
27+
28+
printf("\n");
29+
30+
fflush(stdout);
31+
32+
exit(1);
33+
}
34+
35+
void __netlibc_assert_true(bool condition, char *error_message, char *file,
36+
int line) {
37+
if (!condition) {
38+
__assert_fail("ASSERT_TRUE", error_message, file, line);
39+
}
40+
}
41+
42+
void __netlibc_assert_false(bool condition, char *error_message, char *file,
43+
int line) {
44+
if (condition) {
45+
__assert_fail("ASSERT_FALSE", error_message, file, line);
46+
}
47+
}

netlibc/src/log.c

-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
#endif
1919
#endif
2020

21-
#define RED_COLOR 227, 61, 45
22-
#define YELLOW_COLOR 227, 224, 45
23-
2421
void set_color_rgb(u8 r, u8 g, u8 b) { printf("\e[38;2;%d;%d;%dm", r, g, b); }
2522

2623
void reset_color() { printf("\e[0m"); }

netlibc/src/mem.c

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**** mem.c ****
2+
*
3+
* Copyright (c) 2023 ShogAI - https://shog.ai
4+
*
5+
* Part of netlibc, under the MIT License.
6+
* See LICENSE file for license information.
7+
* SPDX-License-Identifier: MIT
8+
*
9+
****/
10+
11+
#include "../include/netlibc.h"
12+
#include "../include/netlibc/log.h"
13+
14+
#include <stdlib.h>
15+
16+
void mem_add_alloation(void *address, size_t size, char *file, u64 line) {
17+
ASSERT_NETLIBC_INIT();
18+
19+
__netlibc_ctx->mem_allocations = realloc(
20+
__netlibc_ctx->mem_allocations,
21+
(__netlibc_ctx->mem_allocations_count + 1) * sizeof(mem_alloc_info_t));
22+
23+
__netlibc_ctx->mem_allocations[__netlibc_ctx->mem_allocations_count].address =
24+
address;
25+
26+
__netlibc_ctx->mem_allocations[__netlibc_ctx->mem_allocations_count].size =
27+
size;
28+
29+
__netlibc_ctx->mem_allocations[__netlibc_ctx->mem_allocations_count].freed =
30+
false;
31+
32+
__netlibc_ctx->mem_allocations[__netlibc_ctx->mem_allocations_count].file =
33+
file;
34+
35+
__netlibc_ctx->mem_allocations[__netlibc_ctx->mem_allocations_count].line =
36+
line;
37+
38+
__netlibc_ctx->mem_allocations_count++;
39+
}
40+
41+
void *__netlibc_malloc(size_t size, char *file, u64 line) {
42+
ASSERT_NETLIBC_INIT();
43+
44+
void *allocated = malloc(size);
45+
46+
if (__netlibc_ctx->mem_debug_enabled) {
47+
mem_add_alloation(allocated, size, file, line);
48+
}
49+
50+
return allocated;
51+
}
52+
53+
void *__netlibc_calloc(u64 count, size_t size) {
54+
void *allocated = calloc(count, size);
55+
56+
return allocated;
57+
}
58+
59+
void *__netlibc_realloc(void *pre_allocated, size_t new_size) {
60+
void *reallocated = realloc(pre_allocated, new_size);
61+
62+
return reallocated;
63+
}
64+
65+
void __netlibc_free(void *allocated, char *file, u64 line) {
66+
ASSERT_NETLIBC_INIT();
67+
68+
if (__netlibc_ctx->mem_debug_enabled) {
69+
for (u64 i = 0; i < __netlibc_ctx->mem_allocations_count; i++) {
70+
if (__netlibc_ctx->mem_allocations[i].address == allocated) {
71+
if (__netlibc_ctx->mem_allocations[i].freed) {
72+
printf("[MEM_DEBUG] DOUBLE FREE DETECTED AT %s:" U64_FORMAT_SPECIFIER
73+
"\n",
74+
file, line);
75+
}
76+
77+
__netlibc_ctx->mem_allocations[i].freed = true;
78+
__netlibc_ctx->mem_free_count += 1;
79+
}
80+
}
81+
}
82+
83+
free(allocated);
84+
}

netlibc/src/netlibc.c

+69
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,81 @@
88
*
99
****/
1010

11+
#include "../include/netlibc.h"
12+
#include "../include/netlibc/log.h"
1113
#include "../include/netlibc/string.h"
1214

1315
#include <stdlib.h>
1416
#include <sys/time.h>
1517
#include <time.h>
1618

19+
netlibc_ctx_t *__netlibc_ctx = NULL;
20+
21+
void __netlibc_ctx_init(bool mem_debug_enabled) {
22+
__netlibc_ctx = calloc(1, sizeof(netlibc_ctx_t));
23+
24+
__netlibc_ctx->mem_debug_enabled = mem_debug_enabled;
25+
__netlibc_ctx->mem_allocations = NULL;
26+
__netlibc_ctx->mem_allocations_count = 0;
27+
__netlibc_ctx->mem_free_count = 0;
28+
29+
// Register the cleanup_function
30+
if (atexit(__netlibc_ctx_exit) != 0) {
31+
PANIC("atexit registration failed");
32+
}
33+
}
34+
35+
void __netlibc_ctx_exit() {
36+
if (__netlibc_ctx->mem_debug_enabled) {
37+
printf("[MEM_DEBUG] ALLOCATIONS COUNT: " U64_FORMAT_SPECIFIER " \n",
38+
__netlibc_ctx->mem_allocations_count);
39+
printf("[MEM_DEBUG] FREE COUNT: " U64_FORMAT_SPECIFIER " \n",
40+
__netlibc_ctx->mem_free_count);
41+
42+
u64 allocated_bytes = 0;
43+
for (u64 i = 0; i < __netlibc_ctx->mem_allocations_count; i++) {
44+
allocated_bytes += __netlibc_ctx->mem_allocations[i].size;
45+
}
46+
47+
printf("[MEM_DEBUG] ALLOCATED BYTES: " U64_FORMAT_SPECIFIER " \n",
48+
allocated_bytes);
49+
50+
u64 freed_bytes = 0;
51+
for (u64 i = 0; i < __netlibc_ctx->mem_allocations_count; i++) {
52+
if (__netlibc_ctx->mem_allocations[i].freed) {
53+
freed_bytes += __netlibc_ctx->mem_allocations[i].size;
54+
}
55+
}
56+
57+
printf("[MEM_DEBUG] FREED BYTES: " U64_FORMAT_SPECIFIER " \n", freed_bytes);
58+
59+
printf("\n\n");
60+
61+
u64 leaked_bytes = 0;
62+
for (u64 i = 0; i < __netlibc_ctx->mem_allocations_count; i++) {
63+
if (!__netlibc_ctx->mem_allocations[i].freed) {
64+
leaked_bytes += __netlibc_ctx->mem_allocations[i].size;
65+
66+
printf("[MEM_DEBUG] LEAK OF " U64_FORMAT_SPECIFIER
67+
" BYTES IN %p AT %s:" U64_FORMAT_SPECIFIER "\n",
68+
__netlibc_ctx->mem_allocations[i].size,
69+
__netlibc_ctx->mem_allocations[i].address,
70+
__netlibc_ctx->mem_allocations[i].file,
71+
__netlibc_ctx->mem_allocations[i].line);
72+
}
73+
}
74+
75+
printf("[MEM_DEBUG] LEAKED BYTES: " U64_FORMAT_SPECIFIER " \n",
76+
leaked_bytes);
77+
78+
printf("\n");
79+
}
80+
81+
free(__netlibc_ctx->mem_allocations);
82+
83+
free(__netlibc_ctx);
84+
}
85+
1786
// returns the UNIX timestamp in microseconds
1887
u64 get_timestamp_us() {
1988
struct timeval tv;

0 commit comments

Comments
 (0)