From fdde6bb5a7de9d1b013dd8da48d6a603b482f1f6 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Wed, 30 Mar 2022 01:29:19 +0100 Subject: 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 --- firmware/buflib.c | 22 ++++++++++++---------- 1 file 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 @@ * H - handle table entry pointer * C - pointer to struct buflib_callbacks * c - variable sized string identifier - * L2 - second length marker for string identifier + * L2 - length of the metadata * crc - crc32 protecting buflib metadata integrity * X - actual payload * Y - unallocated space @@ -240,8 +240,8 @@ union buflib_data* handle_to_block(struct buflib_context* ctx, int handle) * has already been allocated but not the data */ if (!data) return NULL; - volatile size_t len = data[-2].val; - return data - (len + 4); + + return data - data[-2].val; } /* Shrink the handle table, returning true if its size was reduced, false if @@ -627,15 +627,15 @@ buffer_alloc: /* Set up the allocated block, by marking the size allocated, and storing * a pointer to the handle. */ - union buflib_data *name_len_slot, *crc_slot; + union buflib_data *header_size_slot, *crc_slot; block->val = size; block[1].handle = handle; block[2].ops = ops; 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->val = 1 + name_len/sizeof(union buflib_data); - crc_slot = (union buflib_data*)(name_len_slot + 1); + header_size_slot = (union buflib_data*)B_ALIGN_UP(block[3].name + name_len); + header_size_slot->val = 5 + name_len/sizeof(union buflib_data); + crc_slot = (union buflib_data*)(header_size_slot + 1); crc_slot->crc = crc_32((void *)block, (crc_slot - block)*sizeof(union buflib_data), 0xffffffff); @@ -742,7 +742,7 @@ static size_t free_space_at_end(struct buflib_context* ctx) { /* subtract 5 elements for - * val, handle, name_len, ops and the handle table entry*/ + * val, handle, meta_len, ops and the handle table entry*/ ptrdiff_t diff = (ctx->last_handle - ctx->alloc_end - 5); diff -= 16; /* space for future handles */ diff *= sizeof(union buflib_data); /* make it bytes */ @@ -933,9 +933,11 @@ const char* buflib_get_name(struct buflib_context *ctx, int handle) { union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data)); size_t len = data[-2].val; - if (len <= 1) + if (len <= 5) return NULL; - return data[-len-1].name; + + data -= len; + return data[3].name; } #ifdef DEBUG -- cgit v1.2.3