Skip to content

Commit 00de772

Browse files
committed
Introduce realloc(...)
1 parent 1d4b7cc commit 00de772

File tree

5 files changed

+76
-7
lines changed

5 files changed

+76
-7
lines changed

src/usr/include/stdlib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ int abs(int a);
2121
int benchmark_get_heap_usage();
2222
int benchmark_get_heap_area();
2323
void *malloc(size_t size);
24+
void *realloc(void *ptr, size_t size);
2425
void free(void *ptr);
2526

2627
void atexit(void (*)(void));

src/usr/include/string.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ int strcmpi(const char *l, const char *r);
1212
int strlen(const char *str);
1313
char *strcpy(char *dest, const char *src);
1414
char *strncpy(char *dest, const char *src, size_t n);
15-
void *memcpy(void *dest, const void *src, unsigned int n);
15+
void *memcpy(void *dest, const void *src, size_t n);
1616
void *memset(void *dest, const unsigned char c, size_t n);
1717

1818
char *strchr(const char *str, char ch);

src/usr/lib/stdlib.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ static inline union heap_entry *heap_prev_block(union heap_entry *current,
265265
return block;
266266
}
267267

268+
static inline union heap_entry *
269+
heap_block_from_usermemory(void *ptr, int verify_signature) {
270+
union heap_entry *block = ptr - HEAP_HEADER_SIZE;
271+
if (verify_signature) {
272+
heap_assert(block->content.signature == HEAP_ENTRY_SIGNATURE,
273+
"heap_block_from_usermemory, invalid signature");
274+
}
275+
return block;
276+
}
277+
268278
static inline union heap_entry *heap_push_back(union heap_entry *olast,
269279
size_t new_size) {
270280
heap_assert(olast->content.state == HEAP_BLOCK_LAST,
@@ -389,6 +399,10 @@ static inline union heap_entry *heap_get_free_block(size_t new_size) {
389399

390400
void *malloc(size_t size) {
391401
heap_may_init();
402+
if (size == 0) {
403+
// do nothing
404+
return NULL;
405+
}
392406
// allocates in chunk of 4
393407
size = ((size + 3) >> 2) << 2;
394408
// allocate header
@@ -402,13 +416,13 @@ void *malloc(size_t size) {
402416
}
403417

404418
void free(void *ptr) {
405-
if (ptr == NULL)
406-
return;
407419
heap_may_init();
420+
if (ptr == NULL) {
421+
// do nothing
422+
return;
423+
}
408424

409-
// current version of malloc is non-optimal and doesn't
410-
// do any free operation.
411-
union heap_entry *header = ptr - HEAP_HEADER_SIZE;
425+
union heap_entry *header = heap_block_from_usermemory(ptr, 1);
412426
if (header->content.state != HEAP_BLOCK_ALLOCATED) {
413427
// trying to free unallocated memory
414428
return;
@@ -420,3 +434,28 @@ void free(void *ptr) {
420434
heap_freeblocks_merge(header);
421435
#endif
422436
}
437+
438+
void *realloc(void *ptr, size_t size) {
439+
heap_may_init();
440+
if (ptr == NULL) {
441+
return malloc(size);
442+
}
443+
444+
union heap_entry *header = heap_block_from_usermemory(ptr, 1);
445+
size_t old_size = header->content.size - HEAP_HEADER_SIZE;
446+
447+
if (old_size == size) {
448+
// no need to allocate or free memory
449+
return ptr;
450+
}
451+
452+
// allocate memory for new data size
453+
void *newdata = malloc(size);
454+
// copy data
455+
size_t copy_size = min(size, old_size);
456+
memcpy(newdata, ptr, copy_size);
457+
// free old data
458+
free(ptr);
459+
460+
return newdata;
461+
}

src/usr/lib/string.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ char *strncpy(char *dst, const char *src, size_t n) {
6767
return og_dst;
6868
}
6969

70-
void *memcpy(void *dst, const void *src, unsigned int n) {
70+
void *memcpy(void *dst, const void *src, size_t n) {
7171
void *og_dst = dst;
7272
while (n--) {
7373
*(char *)(dst++) = *(char *)(src++);

src/usr/local/src/test-stdlib.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,34 @@ void test_malloc_free() {
9595
}
9696
}
9797

98+
void test_realloc() {
99+
// allocate memory
100+
std::uint8_t *data =
101+
(std::uint8_t *)std::realloc(NULL, sizeof(std::uint8_t) * 2);
102+
ASSERT_TRUE(data);
103+
data[0] = 100;
104+
data[1] = 101;
105+
106+
// upsize memory
107+
data = (std::uint8_t *)std::realloc(data, sizeof(std::uint8_t) * 4);
108+
ASSERT_TRUE(data);
109+
ASSERT_EQ(data[0], 100);
110+
ASSERT_EQ(data[1], 101);
111+
data[2] = 102;
112+
data[3] = 103;
113+
114+
// downsize memory
115+
data = (std::uint8_t *)std::realloc(data, sizeof(std::uint8_t) * 3);
116+
ASSERT_TRUE(data);
117+
ASSERT_EQ(data[0], 100);
118+
ASSERT_EQ(data[1], 101);
119+
ASSERT_EQ(data[2], 102);
120+
121+
// free memory
122+
data = (std::uint8_t *)std::realloc(data, 0);
123+
ASSERT_FALSE(data);
124+
}
125+
98126
int main(int argc, char *argv[]) {
99127
TEST_INIT();
100128

@@ -105,6 +133,7 @@ int main(int argc, char *argv[]) {
105133
RUN_TEST(test_itoa);
106134
RUN_TEST(test_ftoa);
107135
RUN_TEST(test_malloc_free);
136+
RUN_TEST(test_realloc);
108137

109138
TEST_SUMMARY();
110139
return 0;

0 commit comments

Comments
 (0)