diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 26f44cb597e..88dd371760b 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -27,6 +27,10 @@ /* Operating System Interface */ +struct os_mem_hdr { + size_t length; /* number of bytes in the block */ +}; + ssize_t os_read(int fd, void *buf, size_t count) { return read(fd, buf, count); @@ -128,8 +132,45 @@ void os_tty_raw(int fd) void *os_malloc(size_t length) { - return mmap(NULL, length, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + struct os_mem_hdr *hdr; + + hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (hdr == MAP_FAILED) + return NULL; + hdr->length = length; + + return hdr + 1; +} + +void *os_free(void *ptr) +{ + struct os_mem_hdr *hdr = ptr; + + hdr--; + if (ptr) + munmap(hdr, hdr->length + sizeof(*hdr)); +} + +void *os_realloc(void *ptr, size_t length) +{ + struct os_mem_hdr *hdr = ptr; + void *buf = NULL; + + hdr--; + if (length != 0) { + buf = os_malloc(length); + if (!buf) + return buf; + if (ptr) { + if (length > hdr->length) + length = hdr->length; + memcpy(buf, ptr, length); + } + } + os_free(ptr); + + return buf; } void os_usleep(unsigned long usec) diff --git a/include/os.h b/include/os.h index 950433daa32..1575a969222 100644 --- a/include/os.h +++ b/include/os.h @@ -106,6 +106,35 @@ void os_tty_raw(int fd); */ void *os_malloc(size_t length); +/** + * Free memory previous allocated with os_malloc()/os_realloc() + * + * This returns the memory to the OS. + * + * \param ptr Pointer to memory block to free + */ +void *os_free(void *ptr); + +/** + * Reallocate previously-allocated memory to increase/decrease space + * + * This works in a similar way to the C library realloc() function. If + * length is 0, then ptr is freed. Otherwise the space used by ptr is + * expanded or reduced depending on whether length is larger or smaller + * than before. + * + * If ptr is NULL, then this is similar to calling os_malloc(). + * + * This function may need to move the memory block to make room for any + * extra space, in which case the new pointer is returned. + * + * \param ptr Pointer to memory block to reallocate + * \param length New length for memory block + * \return pointer to new memory block, or NULL on failure or if length + * is 0. + */ +void *os_realloc(void *ptr, size_t length); + /** * Access to the usleep function of the os *