forked from len0rd/rockbox
buflib: Properly support allocations without any name, to avoid wasting space
in micro-allocation scenarios. Change-Id: I97a065bcfba8e0fda9b1670445e839e267c769c8
This commit is contained in:
parent
d66346789c
commit
4ce1deacfd
4 changed files with 27 additions and 22 deletions
|
@ -105,6 +105,8 @@ void
|
||||||
buflib_init(struct buflib_context *ctx, void *buf, size_t size)
|
buflib_init(struct buflib_context *ctx, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
union buflib_data *bd_buf = buf;
|
union buflib_data *bd_buf = buf;
|
||||||
|
BDEBUGF("buflib initialized with %lu.%02lu kiB",
|
||||||
|
(unsigned long)size / 1024, ((unsigned long)size%1000)/10);
|
||||||
|
|
||||||
/* Align on sizeof(buflib_data), to prevent unaligned access */
|
/* Align on sizeof(buflib_data), to prevent unaligned access */
|
||||||
ALIGN_BUFFER(bd_buf, size, sizeof(union buflib_data));
|
ALIGN_BUFFER(bd_buf, size, sizeof(union buflib_data));
|
||||||
|
@ -119,9 +121,6 @@ buflib_init(struct buflib_context *ctx, void *buf, size_t size)
|
||||||
*/
|
*/
|
||||||
ctx->alloc_end = bd_buf;
|
ctx->alloc_end = bd_buf;
|
||||||
ctx->compact = true;
|
ctx->compact = true;
|
||||||
|
|
||||||
BDEBUGF("buflib initialized with %lu.%2lu kiB",
|
|
||||||
(unsigned long)size / 1024, ((unsigned long)size%1000)/10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buflib_context_relocate(struct buflib_context *ctx, void *buf)
|
bool buflib_context_relocate(struct buflib_context *ctx, void *buf)
|
||||||
|
@ -206,12 +205,16 @@ void handle_free(struct buflib_context *ctx, union buflib_data *handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the start block of an allocation */
|
/* Get the start block of an allocation */
|
||||||
static union buflib_data* handle_to_block(struct buflib_context* ctx, int handle)
|
static inline
|
||||||
|
union buflib_data* handle_to_block(struct buflib_context* ctx, int handle)
|
||||||
{
|
{
|
||||||
union buflib_data* name_field =
|
union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data));
|
||||||
(union buflib_data*)buflib_get_name(ctx, handle);
|
/* this is a valid case, e.g. during buflib_alloc_ex() when the handle
|
||||||
|
* has already been allocated but not the data */
|
||||||
return name_field ? name_field - 3 : NULL;
|
if (!data)
|
||||||
|
return NULL;
|
||||||
|
volatile size_t len = data[-2].val;
|
||||||
|
return data - (len + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shrink the handle table, returning true if its size was reduced, false if
|
/* Shrink the handle table, returning true if its size was reduced, false if
|
||||||
|
@ -480,7 +483,7 @@ buflib_buffer_in(struct buflib_context *ctx, int size)
|
||||||
int
|
int
|
||||||
buflib_alloc(struct buflib_context *ctx, size_t size)
|
buflib_alloc(struct buflib_context *ctx, size_t size)
|
||||||
{
|
{
|
||||||
return buflib_alloc_ex(ctx, size, "<anonymous>", NULL);
|
return buflib_alloc_ex(ctx, size, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a buffer of size bytes, returning a handle for it.
|
/* Allocate a buffer of size bytes, returning a handle for it.
|
||||||
|
@ -588,7 +591,8 @@ buffer_alloc:
|
||||||
block->val = size;
|
block->val = size;
|
||||||
block[1].handle = handle;
|
block[1].handle = handle;
|
||||||
block[2].ops = ops;
|
block[2].ops = ops;
|
||||||
strcpy(block[3].name, name);
|
if (name_len > 0)
|
||||||
|
strcpy(block[3].name, name);
|
||||||
name_len_slot = (union buflib_data*)B_ALIGN_UP(block[3].name + name_len);
|
name_len_slot = (union buflib_data*)B_ALIGN_UP(block[3].name + name_len);
|
||||||
name_len_slot->val = 1 + name_len/sizeof(union buflib_data);
|
name_len_slot->val = 1 + name_len/sizeof(union buflib_data);
|
||||||
crc_slot = (union buflib_data*)(name_len_slot + 1);
|
crc_slot = (union buflib_data*)(name_len_slot + 1);
|
||||||
|
@ -599,7 +603,7 @@ buffer_alloc:
|
||||||
|
|
||||||
BDEBUGF("buflib_alloc_ex: size=%d handle=%p clb=%p crc=0x%0x name=\"%s\"\n",
|
BDEBUGF("buflib_alloc_ex: size=%d handle=%p clb=%p crc=0x%0x name=\"%s\"\n",
|
||||||
(unsigned int)size, (void *)handle, (void *)ops,
|
(unsigned int)size, (void *)handle, (void *)ops,
|
||||||
(unsigned int)crc_slot->crc, block[3].name);
|
(unsigned int)crc_slot->crc, name ? block[3].name:"");
|
||||||
|
|
||||||
block += size;
|
block += size;
|
||||||
/* alloc_end must be kept current if we're taking the last block. */
|
/* alloc_end must be kept current if we're taking the last block. */
|
||||||
|
@ -889,8 +893,6 @@ buflib_shrink(struct buflib_context* ctx, int handle, void* new_start, size_t ne
|
||||||
const char* buflib_get_name(struct buflib_context *ctx, int handle)
|
const char* buflib_get_name(struct buflib_context *ctx, int handle)
|
||||||
{
|
{
|
||||||
union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data));
|
union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data));
|
||||||
if (!data)
|
|
||||||
return NULL;
|
|
||||||
size_t len = data[-2].val;
|
size_t len = data[-2].val;
|
||||||
if (len <= 1)
|
if (len <= 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -87,6 +87,12 @@ bool core_shrink(int handle, void* new_start, size_t new_size)
|
||||||
return buflib_shrink(&core_ctx, handle, new_start, new_size);
|
return buflib_shrink(&core_ctx, handle, new_start, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* core_get_name(int handle)
|
||||||
|
{
|
||||||
|
const char *name = buflib_get_name(&core_ctx, handle);
|
||||||
|
return name ?: "<anonymous>";
|
||||||
|
}
|
||||||
|
|
||||||
int core_get_num_blocks(void)
|
int core_get_num_blocks(void)
|
||||||
{
|
{
|
||||||
return buflib_get_num_blocks(&core_ctx);
|
return buflib_get_num_blocks(&core_ctx);
|
||||||
|
|
|
@ -303,12 +303,14 @@ void buflib_buffer_in(struct buflib_context *ctx, int size);
|
||||||
/* debugging */
|
/* debugging */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name, as given to core_alloc() and core_allloc_ex(), of the
|
* Returns the name, as given to buflib_alloc() and buflib_allloc_ex(), of the
|
||||||
* allocation associated with the given handle
|
* allocation associated with the given handle. As naming allocations
|
||||||
|
* is optional, there might be no name associated.
|
||||||
*
|
*
|
||||||
* handle: The handle indicating the allocation
|
* handle: The handle indicating the allocation
|
||||||
*
|
*
|
||||||
* Returns: A pointer to the string identifier of the allocation
|
* Returns: A pointer to the string identifier of the allocation, or NULL
|
||||||
|
* if none was specified with buflib_alloc_ex/(.
|
||||||
*/
|
*/
|
||||||
const char* buflib_get_name(struct buflib_context *ctx, int handle);
|
const char* buflib_get_name(struct buflib_context *ctx, int handle);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ bool core_shrink(int handle, void* new_start, size_t new_size);
|
||||||
int core_free(int handle);
|
int core_free(int handle);
|
||||||
size_t core_available(void);
|
size_t core_available(void);
|
||||||
size_t core_allocatable(void);
|
size_t core_allocatable(void);
|
||||||
|
const char* core_get_name(int handle);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void core_check_valid(void);
|
void core_check_valid(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,10 +44,4 @@ static inline void* core_get_data(int handle)
|
||||||
return buflib_get_data(&core_ctx, handle);
|
return buflib_get_data(&core_ctx, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char* core_get_name(int handle)
|
|
||||||
{
|
|
||||||
extern struct buflib_context core_ctx;
|
|
||||||
return buflib_get_name(&core_ctx, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __CORE_ALLOC_H__ */
|
#endif /* __CORE_ALLOC_H__ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue