From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Sat, 6 Feb 2021 09:57:32 -0700 Subject: [PATCH v4 6/9] sandbox: Add os_realloc() In-Reply-To: <20210206165736.3491584-1-sjg@chromium.org> References: <20210206165736.3491584-1-sjg@chromium.org> Message-ID: <20210206165736.3491584-6-sjg@chromium.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de We provide os_malloc() and os_free() but not os_realloc(). Add this, following the usual semantics. Also update os_malloc() to behave correctly when passed a zero size. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- (no changes since v3) Changes in v3: - Add comments as to why we have os_malloc() and os_realloc() Changes in v2: - Add new patch to add os_realloc() arch/sandbox/cpu/os.c | 48 +++++++++++++++++++++++++++++++++++++++++++ include/os.h | 12 ++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 3d8af0a52bb..d23aad318be 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -267,11 +267,18 @@ void os_tty_raw(int fd, bool allow_sigs) signal(SIGINT, os_sigint_handler); } +/* + * Provide our own malloc so we don't use space in the sandbox ram_buf for + * allocations that are internal to sandbox, or need to be done before U-Boot's + * malloc() is ready. + */ void *os_malloc(size_t length) { int page_size = getpagesize(); struct os_mem_hdr *hdr; + if (!length) + return NULL; /* * Use an address that is hopefully available to us so that pointers * to this memory are fairly obvious. If we end up with a different @@ -298,6 +305,47 @@ void os_free(void *ptr) } } +/* These macros are from kernel.h but not accessible in this file */ +#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1) +#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + +/* + * Provide our own malloc so we don't use space in the sandbox ram_buf for + * allocations that are internal to sandbox, or need to be done before U-Boot's + * malloc() is ready. + */ +void *os_realloc(void *ptr, size_t length) +{ + int page_size = getpagesize(); + struct os_mem_hdr *hdr; + void *new_ptr; + + /* Reallocating a NULL pointer is just an alloc */ + if (!ptr) + return os_malloc(length); + + /* Changing a length to 0 is just a free */ + if (length) { + os_free(ptr); + return NULL; + } + + /* + * If the new size is the same number of pages as the old, nothing to + * do. There isn't much point in shrinking things + */ + hdr = ptr - page_size; + if (ALIGN(length, page_size) <= ALIGN(hdr->length, page_size)) + return ptr; + + /* We have to grow it, so allocate something new */ + new_ptr = os_malloc(length); + memcpy(new_ptr, ptr, hdr->length); + os_free(ptr); + + return new_ptr; +} + void os_usleep(unsigned long usec) { usleep(usec); diff --git a/include/os.h b/include/os.h index 65bcb232cab..fd010cfee83 100644 --- a/include/os.h +++ b/include/os.h @@ -114,7 +114,7 @@ void os_fd_restore(void); * os_malloc() - aquires some memory from the underlying os. * * @length: Number of bytes to be allocated - * Return: Pointer to length bytes or NULL on error + * Return: Pointer to length bytes or NULL if @length is 0 or on error */ void *os_malloc(size_t length); @@ -127,6 +127,16 @@ void *os_malloc(size_t length); */ void os_free(void *ptr); +/** + * os_realloc() - reallocate memory + * + * This follows the semantics of realloc(), so can perform an os_malloc() or + * os_free() depending on @ptr and @length. + * + * Return: Pointer to reallocated memory or NULL if @length is 0 + */ +void *os_realloc(void *ptr, size_t length); + /** * os_usleep() - access to the usleep function of the os * -- 2.30.0.478.g8a0d178c01-goog