summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-03-30 01:29:19 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-09-19 15:09:51 -0400
commitfdde6bb5a7de9d1b013dd8da48d6a603b482f1f6 (patch)
treed7fd35a59d28d53c801c1ba14dec033f1d55663a
parentef476ba298e52e96f981458784c1e7697a856ec7 (diff)
downloadrockbox-fdde6bb5a7de9d1b013dd8da48d6a603b482f1f6.tar.gz
rockbox-fdde6bb5a7de9d1b013dd8da48d6a603b482f1f6.zip
buflib: optimize getting start of block from end of block
The block header has a variable length due to the embedded name. The name length is stored at the back of the header after the name, in order to allow finding the start of the header if only the user data pointer is known (eg. from the handle table). The name length is actually not interesting in itself; storing the total length of the block header instead is marginally more efficient, saving one addition in handle_to_block(). Instead the extra arithmetic must be done by buflib_get_name(), which is a much less common operation than handle_to_block(). Change-Id: Ia339a1d2f556a11a49deae0871203e70548bd234
-rw-r--r--firmware/buflib.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/firmware/buflib.c b/firmware/buflib.c
index dcef84d5c1..e7835c8a2e 100644
--- a/firmware/buflib.c
+++ b/firmware/buflib.c
@@ -65,7 +65,7 @@
65 * H - handle table entry pointer 65 * H - handle table entry pointer
66 * C - pointer to struct buflib_callbacks 66 * C - pointer to struct buflib_callbacks
67 * c - variable sized string identifier 67 * c - variable sized string identifier
68 * L2 - second length marker for string identifier 68 * L2 - length of the metadata
69 * crc - crc32 protecting buflib metadata integrity 69 * crc - crc32 protecting buflib metadata integrity
70 * X - actual payload 70 * X - actual payload
71 * Y - unallocated space 71 * Y - unallocated space
@@ -240,8 +240,8 @@ union buflib_data* handle_to_block(struct buflib_context* ctx, int handle)
240 * has already been allocated but not the data */ 240 * has already been allocated but not the data */
241 if (!data) 241 if (!data)
242 return NULL; 242 return NULL;
243 volatile size_t len = data[-2].val; 243
244 return data - (len + 4); 244 return data - data[-2].val;
245} 245}
246 246
247/* Shrink the handle table, returning true if its size was reduced, false if 247/* Shrink the handle table, returning true if its size was reduced, false if
@@ -627,15 +627,15 @@ buffer_alloc:
627 /* Set up the allocated block, by marking the size allocated, and storing 627 /* Set up the allocated block, by marking the size allocated, and storing
628 * a pointer to the handle. 628 * a pointer to the handle.
629 */ 629 */
630 union buflib_data *name_len_slot, *crc_slot; 630 union buflib_data *header_size_slot, *crc_slot;
631 block->val = size; 631 block->val = size;
632 block[1].handle = handle; 632 block[1].handle = handle;
633 block[2].ops = ops; 633 block[2].ops = ops;
634 if (name_len > 0) 634 if (name_len > 0)
635 strcpy(block[3].name, name); 635 strcpy(block[3].name, name);
636 name_len_slot = (union buflib_data*)B_ALIGN_UP(block[3].name + name_len); 636 header_size_slot = (union buflib_data*)B_ALIGN_UP(block[3].name + name_len);
637 name_len_slot->val = 1 + name_len/sizeof(union buflib_data); 637 header_size_slot->val = 5 + name_len/sizeof(union buflib_data);
638 crc_slot = (union buflib_data*)(name_len_slot + 1); 638 crc_slot = (union buflib_data*)(header_size_slot + 1);
639 crc_slot->crc = crc_32((void *)block, 639 crc_slot->crc = crc_32((void *)block,
640 (crc_slot - block)*sizeof(union buflib_data), 640 (crc_slot - block)*sizeof(union buflib_data),
641 0xffffffff); 641 0xffffffff);
@@ -742,7 +742,7 @@ static size_t
742free_space_at_end(struct buflib_context* ctx) 742free_space_at_end(struct buflib_context* ctx)
743{ 743{
744 /* subtract 5 elements for 744 /* subtract 5 elements for
745 * val, handle, name_len, ops and the handle table entry*/ 745 * val, handle, meta_len, ops and the handle table entry*/
746 ptrdiff_t diff = (ctx->last_handle - ctx->alloc_end - 5); 746 ptrdiff_t diff = (ctx->last_handle - ctx->alloc_end - 5);
747 diff -= 16; /* space for future handles */ 747 diff -= 16; /* space for future handles */
748 diff *= sizeof(union buflib_data); /* make it bytes */ 748 diff *= sizeof(union buflib_data); /* make it bytes */
@@ -933,9 +933,11 @@ const char* buflib_get_name(struct buflib_context *ctx, int handle)
933{ 933{
934 union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data)); 934 union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data));
935 size_t len = data[-2].val; 935 size_t len = data[-2].val;
936 if (len <= 1) 936 if (len <= 5)
937 return NULL; 937 return NULL;
938 return data[-len-1].name; 938
939 data -= len;
940 return data[3].name;
939} 941}
940 942
941#ifdef DEBUG 943#ifdef DEBUG