Skip to content

Commit

Permalink
eliminate rc_scratch_buffer_t (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamiras authored Nov 12, 2023
1 parent 8a717b1 commit ff8e169
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 83 deletions.
56 changes: 6 additions & 50 deletions src/rcheevos/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

void* rc_alloc_scratch(void* pointer, int32_t* offset, uint32_t size, uint32_t alignment, rc_scratch_t* scratch, uint32_t scratch_object_pointer_offset)
{
rc_scratch_buffer_t* buffer;
void* data;

/* if we have a real buffer, then allocate the data there */
if (pointer)
Expand All @@ -19,49 +19,13 @@ void* rc_alloc_scratch(void* pointer, int32_t* offset, uint32_t size, uint32_t a
}

/* find a scratch buffer to hold the temporary data */
buffer = &scratch->buffer;
do {
const uint32_t aligned_buffer_offset = (buffer->offset + alignment - 1) & ~(alignment - 1);
if (aligned_buffer_offset < sizeof(buffer->buffer)) {
const uint32_t remaining = sizeof(buffer->buffer) - aligned_buffer_offset;

if (remaining >= size) {
/* claim the required space from an existing buffer */
return rc_alloc(buffer->buffer, &buffer->offset, size, alignment, NULL, -1);
}
}

if (!buffer->next)
break;

buffer = buffer->next;
} while (1);

/* not enough space in any existing buffer, allocate more */
if (size > (uint32_t)sizeof(buffer->buffer)) {
/* caller is asking for more than we can fit in a standard rc_scratch_buffer_t.
* leverage the fact that the buffer is the last field and extend its size.
* this chunk will be exactly large enough to hold the needed data, and since offset
* will exceed sizeof(buffer->buffer), it will never be eligible to hold anything else.
*/
const size_t needed = sizeof(rc_scratch_buffer_t) - sizeof(buffer->buffer) + size;
buffer->next = (rc_scratch_buffer_t*)malloc(needed);
}
else {
buffer->next = (rc_scratch_buffer_t*)malloc(sizeof(rc_scratch_buffer_t));
}

if (!buffer->next) {
data = rc_buffer_alloc(&scratch->buffer, size);
if (!data) {
*offset = RC_OUT_OF_MEMORY;
return NULL;
}

buffer = buffer->next;
buffer->offset = 0;
buffer->next = NULL;

/* claim the required space from the new buffer */
return rc_alloc(buffer->buffer, &buffer->offset, size, alignment, NULL, -1);
return data;
}

void* rc_alloc(void* pointer, int32_t* offset, uint32_t size, uint32_t alignment, rc_scratch_t* scratch, uint32_t scratch_object_pointer_offset) {
Expand Down Expand Up @@ -137,9 +101,8 @@ void rc_init_parse_state(rc_parse_state_t* parse, void* buffer, lua_State* L, in
parse->L = L;
parse->funcs_ndx = funcs_ndx;
parse->buffer = buffer;
parse->scratch.buffer.offset = 0;
parse->scratch.buffer.next = NULL;
parse->scratch.strings = NULL;
rc_buffer_init(&parse->scratch.buffer);
memset(&parse->scratch.objs, 0, sizeof(parse->scratch.objs));
parse->first_memref = 0;
parse->variables = 0;
Expand All @@ -151,12 +114,5 @@ void rc_init_parse_state(rc_parse_state_t* parse, void* buffer, lua_State* L, in

void rc_destroy_parse_state(rc_parse_state_t* parse)
{
rc_scratch_buffer_t* buffer = parse->scratch.buffer.next;
rc_scratch_buffer_t* next;

while (buffer) {
next = buffer->next;
free(buffer);
buffer = next;
}
rc_buffer_destroy(&parse->scratch.buffer);
}
10 changes: 2 additions & 8 deletions src/rcheevos/rc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define RC_INTERNAL_H

#include "rc_runtime_types.h"
#include "../rc_util.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -39,15 +40,8 @@ RC_ALLOW_ALIGN(char)
/* force alignment to 4 bytes on 32-bit systems, or 8 bytes on 64-bit systems */
#define RC_ALIGN(n) (((n) + (sizeof(void*)-1)) & ~(sizeof(void*)-1))

typedef struct rc_scratch_buffer {
struct rc_scratch_buffer* next;
int32_t offset;
uint8_t buffer[512 - 16];
}
rc_scratch_buffer_t;

typedef struct {
rc_scratch_buffer_t buffer;
rc_buffer_t buffer;
rc_scratch_string_t* strings;

struct objs {
Expand Down
30 changes: 5 additions & 25 deletions src/rcheevos/richpresence.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@ static void rc_rebalance_richpresence_lookup_rebuild(rc_richpresence_lookup_item
static void rc_rebalance_richpresence_lookup(rc_richpresence_lookup_item_t** root, rc_parse_state_t* parse)
{
rc_richpresence_lookup_item_t** items;
rc_scratch_buffer_t* buffer;
int index;
int size;

Expand All @@ -288,39 +287,20 @@ static void rc_rebalance_richpresence_lookup(rc_richpresence_lookup_item_t** roo
if (count < 3)
return;

/* allocate space for the flattened list - prefer scratch memory if available */
/* allocate space for the flattened list in scratch memory */
size = count * sizeof(rc_richpresence_lookup_item_t*);
buffer = &parse->scratch.buffer;
do {
const int aligned_offset = RC_ALIGN(buffer->offset);
const int remaining = sizeof(buffer->buffer) - aligned_offset;

if (remaining >= size) {
items = (rc_richpresence_lookup_item_t**)&buffer->buffer[aligned_offset];
break;
}

buffer = buffer->next;
if (buffer == NULL) {
/* could not find large enough block of scratch memory; allocate. if allocation fails,
* we can still use the unbalanced tree, so just bail out */
items = (rc_richpresence_lookup_item_t**)malloc(size);
if (items == NULL)
return;
items = (rc_richpresence_lookup_item_t**)rc_buffer_alloc(&parse->scratch.buffer, size);

break;
}
} while (1);
/* if allocation fails, we can still use the unbalanced tree, so just bail out */
if (items == NULL)
return;

/* flatten the list */
index = 0;
rc_rebalance_richpresence_lookup_get_items(*root, items, &index);

/* and rebuild it as a balanced tree */
rc_rebalance_richpresence_lookup_rebuild(root, items, 0, count - 1);

if (buffer == NULL)
free(items);
}

static void rc_insert_richpresence_lookup_item(rc_richpresence_lookup_t* lookup,
Expand Down

0 comments on commit ff8e169

Please sign in to comment.