diff options
Diffstat (limited to 'src/basecmd.c')
-rw-r--r-- | src/basecmd.c | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/src/basecmd.c b/src/basecmd.c index 4b4eca45..639add97 100644 --- a/src/basecmd.c +++ b/src/basecmd.c @@ -17,26 +17,53 @@ * Move queue ****************************************************************/ -static struct move *move_list, *move_free_list; +struct move_freed { + struct move_freed *next; +}; + +static struct move_freed *move_free_list; +static void *move_list; static uint16_t move_count; +static uint8_t move_item_size; + +// Is the config and move queue finalized? +static int +is_finalized(void) +{ + return !!move_count; +} +// Free previously allocated storage from move_alloc(). Caller must +// disable irqs. void -move_free(struct move *m) +move_free(void *m) { - m->next = move_free_list; - move_free_list = m; + struct move_freed *mf = m; + mf->next = move_free_list; + move_free_list = mf; } -struct move * +// Allocate runtime storage +void * move_alloc(void) { irqstatus_t flag = irq_save(); - struct move *m = move_free_list; - if (!m) + struct move_freed *mf = move_free_list; + if (!mf) shutdown("Move queue empty"); - move_free_list = m->next; + move_free_list = mf->next; irq_restore(flag); - return m; + return mf; +} + +// Request minimum size of runtime allocations returned by move_alloc() +void +move_request_size(int size) +{ + if (size > UINT8_MAX || is_finalized()) + shutdown("Invalid move request size"); + if (size > move_item_size) + move_item_size = size; } static void @@ -46,13 +73,28 @@ move_reset(void) return; // Add everything in move_list to the free list. uint32_t i; - for (i=0; i<move_count-1; i++) - move_list[i].next = &move_list[i+1]; - move_list[move_count-1].next = NULL; - move_free_list = &move_list[0]; + for (i=0; i<move_count-1; i++) { + struct move_freed *mf = move_list + i*move_item_size; + mf->next = move_list + (i + 1)*move_item_size; + } + struct move_freed *mf = move_list + (move_count - 1)*move_item_size; + mf->next = NULL; + move_free_list = move_list; } DECL_SHUTDOWN(move_reset); +static void +move_finalize(void) +{ + move_request_size(sizeof(*move_free_list)); + uint16_t count = alloc_maxsize(move_item_size*1024) / move_item_size; + move_list = malloc(count * move_item_size); + if (!count || !move_list) + shutdown("move queue malloc failed"); + move_count = count; + move_reset(); +} + /**************************************************************** * Generic object ids (oid) @@ -64,8 +106,6 @@ struct oid_s { static struct oid_s *oids; static uint8_t num_oid; -static uint32_t config_crc; -static uint8_t config_finalized; void * lookup_oid(uint8_t oid, void *type) @@ -78,7 +118,7 @@ lookup_oid(uint8_t oid, void *type) static void assign_oid(uint8_t oid, void *type, void *data) { - if (oid >= num_oid || oids[oid].type || config_finalized) + if (oid >= num_oid || oids[oid].type || is_finalized()) shutdown("Can't assign oid"); oids[oid].type = type; oids[oid].data = data; @@ -124,27 +164,28 @@ command_allocate_oids(uint32_t *args) } DECL_COMMAND(command_allocate_oids, "allocate_oids count=%c"); + +/**************************************************************** + * Config CRC + ****************************************************************/ + +static uint32_t config_crc; + void command_get_config(uint32_t *args) { sendf("config is_config=%c crc=%u move_count=%hu" - , config_finalized, config_crc, move_count); + , is_finalized(), config_crc, move_count); } DECL_COMMAND_FLAGS(command_get_config, HF_IN_SHUTDOWN, "get_config"); void command_finalize_config(uint32_t *args) { - if (!oids || config_finalized) + if (!oids || is_finalized()) shutdown("Can't finalize"); - uint16_t count = alloc_maxsize(sizeof(*move_list)*1024) / sizeof(*move_list); - move_list = malloc(count * sizeof(*move_list)); - if (!count || !move_list) - shutdown("malloc failed"); - move_count = count; - move_reset(); + move_finalize(); config_crc = args[0]; - config_finalized = 1; command_get_config(NULL); } DECL_COMMAND(command_finalize_config, "finalize_config crc=%u"); |