Skip to content

Commit

Permalink
atom_table: add opts parameter to atom_table_ensure_atom
Browse files Browse the repository at this point in the history
Add also option flags for `AtomTableAlreadyExisting` and
`AtomTableCopyAtom`.

Signed-off-by: Davide Bettio <davide@uninstall.it>
  • Loading branch information
bettio committed Oct 29, 2023
1 parent 5024662 commit f84455b
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 157 deletions.
18 changes: 16 additions & 2 deletions src/libAtomVM/atom_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ static inline long insert_node(struct AtomTable *table, struct HNodeGroup *node_
return new_index;
}

long atom_table_ensure_atom(struct AtomTable *table, AtomString string)
long atom_table_ensure_atom(
struct AtomTable *table, AtomString string, enum AtomTableCopyOpt opts)
{
unsigned long hash = sdbm_hash(string, atom_string_len(string));
SMP_WRLOCK(table);
Expand All @@ -260,13 +261,26 @@ long atom_table_ensure_atom(struct AtomTable *table, AtomString string)
SMP_UNLOCK(table);
return node->index;
}
if (opts & AtomTableAlreadyExisting) {
return ATOM_TABLE_NOT_FOUND;
}

struct HNodeGroup *node_group = table->last_node_group;
if (!node_group->avail) {
node_group = new_node_group(table, DEFAULT_SIZE);
}

long new_index = insert_node(table, node_group, bucket_index, string);
AtomString maybe_copied = string;
if (opts & AtomTableCopyAtom) {
uint8_t len = *((uint8_t *) string);
uint8_t *buf = malloc(1 + len);
if (IS_NULL_PTR(buf)) {
AVM_ABORT();
}
memcpy(buf, string, 1 + len);
maybe_copied = buf;
}
long new_index = insert_node(table, node_group, bucket_index, maybe_copied);

SMP_UNLOCK(table);
return new_index;
Expand Down
10 changes: 9 additions & 1 deletion src/libAtomVM/atom_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,20 @@

struct AtomTable;

enum AtomTableCopyOpt
{
AtomTableNoOpts = 0,
AtomTableCopyAtom = 1,
AtomTableAlreadyExisting = 2
};

struct AtomTable *atom_table_new();
void atom_table_destroy(struct AtomTable *table);

int atom_table_count(struct AtomTable *table);

long atom_table_ensure_atom(struct AtomTable *table, AtomString string);
long atom_table_ensure_atom(
struct AtomTable *table, AtomString string, enum AtomTableCopyOpt opts);
AtomString atom_table_get_atom_string(struct AtomTable *table, long index);
long atom_table_get_index(struct AtomTable *table, AtomString string);

Expand Down
17 changes: 3 additions & 14 deletions src/libAtomVM/globalcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ int globalcontext_get_registered_process(GlobalContext *glb, int atom_index)

int globalcontext_insert_atom(GlobalContext *glb, AtomString atom_string)
{
long index = atom_table_ensure_atom(glb->atom_table, atom_string);
long index = atom_table_ensure_atom(glb->atom_table, atom_string, AtomTableNoOpts);
if (UNLIKELY(index == ATOM_TABLE_NOT_FOUND)) {
abort();
}
Expand All @@ -398,19 +398,8 @@ int globalcontext_insert_atom(GlobalContext *glb, AtomString atom_string)

int globalcontext_insert_atom_maybe_copy(GlobalContext *glb, AtomString atom_string, int copy)
{
// TODO: this leaks, fix it
if (copy) {
uint8_t len = *((uint8_t *) atom_string);
uint8_t *buf = malloc(1 + len);
if (UNLIKELY(IS_NULL_PTR(buf))) {
fprintf(stderr, "Unable to allocate memory for atom string\n");
AVM_ABORT();
}
memcpy(buf, atom_string, 1 + len);
atom_string = buf;
}

long index = atom_table_ensure_atom(glb->atom_table, atom_string);
long index = atom_table_ensure_atom(
glb->atom_table, atom_string, copy ? AtomTableCopyAtom : AtomTableNoOpts);
return index;
}

Expand Down
2 changes: 1 addition & 1 deletion src/platforms/esp32/components/avm_builtins/gpio_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ Context *gpio_driver_create_port(GlobalContext *global, term opts)
static term gpiodriver_close(Context *ctx)
{
GlobalContext *glb = ctx->global;
int gpio_atom_index = atom_table_ensure_atom(glb->atom_table, gpio_atom);
int gpio_atom_index = atom_table_ensure_atom(glb->atom_table, gpio_atom, AtomTableNoOpts);
if (UNLIKELY(!globalcontext_get_registered_process(glb, gpio_atom_index))) {
return ERROR_ATOM;
}
Expand Down
278 changes: 139 additions & 139 deletions tests/test-structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,140 +278,140 @@ int insert_atoms_into_atom_table(struct AtomTable *table)
{
int decimals_index;

atom_table_ensure_atom(table, false_atom);
atom_table_ensure_atom(table, true_atom);

atom_table_ensure_atom(table, ok_atom);
atom_table_ensure_atom(table, error_atom);

atom_table_ensure_atom(table, undefined_atom);

atom_table_ensure_atom(table, badarg_atom);
atom_table_ensure_atom(table, badarith_atom);
atom_table_ensure_atom(table, badarity_atom);
atom_table_ensure_atom(table, badfun_atom);
atom_table_ensure_atom(table, function_clause_atom);
atom_table_ensure_atom(table, try_clause_atom);
atom_table_ensure_atom(table, out_of_memory_atom);
atom_table_ensure_atom(table, overflow_atom);
atom_table_ensure_atom(table, system_limit_atom);

atom_table_ensure_atom(table, flush_atom);
atom_table_ensure_atom(table, heap_size_atom);
atom_table_ensure_atom(table, latin1_atom);
atom_table_ensure_atom(table, max_heap_size_atom);
atom_table_ensure_atom(table, memory_atom);
atom_table_ensure_atom(table, message_queue_len_atom);
atom_table_ensure_atom(table, puts_atom);
atom_table_ensure_atom(table, stack_size_atom);
atom_table_ensure_atom(table, min_heap_size_atom);
atom_table_ensure_atom(table, process_count_atom);
atom_table_ensure_atom(table, port_count_atom);
atom_table_ensure_atom(table, atom_count_atom);
atom_table_ensure_atom(table, system_architecture_atom);
atom_table_ensure_atom(table, wordsize_atom);

decimals_index = atom_table_ensure_atom(table, decimals_atom);
atom_table_ensure_atom(table, scientific_atom);
atom_table_ensure_atom(table, compact_atom);

atom_table_ensure_atom(table, badmatch_atom);
atom_table_ensure_atom(table, case_clause_atom);
atom_table_ensure_atom(table, if_clause_atom);
atom_table_ensure_atom(table, throw_atom);
atom_table_ensure_atom(table, low_entropy_atom);
atom_table_ensure_atom(table, unsupported_atom);
atom_table_ensure_atom(table, used_atom);
atom_table_ensure_atom(table, all_atom);
atom_table_ensure_atom(table, start_atom);

atom_table_ensure_atom(table, undef_atom);
atom_table_ensure_atom(table, vm_abort_atom);

atom_table_ensure_atom(table, link_atom);
atom_table_ensure_atom(table, monitor_atom);
atom_table_ensure_atom(table, normal_atom);
atom_table_ensure_atom(table, down_atom);
atom_table_ensure_atom(table, process_atom);
atom_table_ensure_atom(table, nocatch_atom);
atom_table_ensure_atom(table, refc_binary_info_atom);

atom_table_ensure_atom(table, noproc_atom);
atom_table_ensure_atom(table, trap_exit_atom);
atom_table_ensure_atom(table, exit_atom);

atom_table_ensure_atom(table, badmap_atom);
atom_table_ensure_atom(table, badkey_atom);
atom_table_ensure_atom(table, none_atom);

atom_table_ensure_atom(table, io_request_atom);
atom_table_ensure_atom(table, io_reply_atom);
atom_table_ensure_atom(table, put_chars_atom);

atom_table_ensure_atom(table, lowercase_exit_atom);
atom_table_ensure_atom(table, atomvm_version_atom);

atom_table_ensure_atom(table, second_atom);
atom_table_ensure_atom(table, millisecond_atom);
atom_table_ensure_atom(table, microsecond_atom);

atom_table_ensure_atom(table, infinity_atom);
atom_table_ensure_atom(table, timeout_value_atom);

atom_table_ensure_atom(table, schedulers_atom);
atom_table_ensure_atom(table, schedulers_online_atom);

atom_table_ensure_atom(table, append_atom);
atom_table_ensure_atom(table, private_append_atom);
atom_table_ensure_atom(table, binary_atom);
atom_table_ensure_atom(table, integer_atom);
atom_table_ensure_atom(table, little_atom);
atom_table_ensure_atom(table, native_atom);
atom_table_ensure_atom(table, string_atom);
atom_table_ensure_atom(table, utf8_atom);
atom_table_ensure_atom(table, utf16_atom);
atom_table_ensure_atom(table, utf32_atom);
atom_table_ensure_atom(table, badrecord_atom);

atom_table_ensure_atom(table, copy_atom);
atom_table_ensure_atom(table, reuse_atom);
atom_table_ensure_atom(table, ensure_at_least_atom);
atom_table_ensure_atom(table, ensure_exactly_atom);
atom_table_ensure_atom(table, skip_atom);
atom_table_ensure_atom(table, get_tail_atom);
atom_table_ensure_atom(table, equal_colon_equal_atom);
atom_table_ensure_atom(table, signed_atom);

atom_table_ensure_atom(table, machine_atom);
atom_table_ensure_atom(table, avm_floatsize_atom);

atom_table_ensure_atom(table, close_atom);
atom_table_ensure_atom(table, closed_atom);
atom_table_ensure_atom(table, port_atom);

atom_table_ensure_atom(table, info_atom);

atom_table_ensure_atom(table, module_atom);

atom_table_ensure_atom(table, select_atom);
atom_table_ensure_atom(table, ready_input_atom);
atom_table_ensure_atom(table, ready_output_atom);

atom_table_ensure_atom(table, attributes_atom);
atom_table_ensure_atom(table, compile_atom);
atom_table_ensure_atom(table, exports_atom);

atom_table_ensure_atom(table, incomplete_atom);

atom_table_ensure_atom(table, kill_atom);
atom_table_ensure_atom(table, killed_atom);
atom_table_ensure_atom(table, links_atom);

atom_table_ensure_atom(table, total_heap_size_atom);
atom_table_ensure_atom(table, atomvm_heap_growth_atom);
atom_table_ensure_atom(table, bounded_free_atom);
atom_table_ensure_atom(table, minimum_atom);
atom_table_ensure_atom(table, fibonacci_atom);
atom_table_ensure_atom(table, false_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, true_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, ok_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, error_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, undefined_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, badarg_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, badarith_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, badarity_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, badfun_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, function_clause_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, try_clause_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, out_of_memory_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, overflow_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, system_limit_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, flush_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, heap_size_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, latin1_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, max_heap_size_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, memory_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, message_queue_len_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, puts_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, stack_size_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, min_heap_size_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, process_count_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, port_count_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, atom_count_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, system_architecture_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, wordsize_atom, AtomTableNoOpts);

decimals_index = atom_table_ensure_atom(table, decimals_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, scientific_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, compact_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, badmatch_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, case_clause_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, if_clause_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, throw_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, low_entropy_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, unsupported_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, used_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, all_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, start_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, undef_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, vm_abort_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, link_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, monitor_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, normal_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, down_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, process_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, nocatch_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, refc_binary_info_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, noproc_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, trap_exit_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, exit_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, badmap_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, badkey_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, none_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, io_request_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, io_reply_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, put_chars_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, lowercase_exit_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, atomvm_version_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, second_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, millisecond_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, microsecond_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, infinity_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, timeout_value_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, schedulers_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, schedulers_online_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, append_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, private_append_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, binary_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, integer_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, little_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, native_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, string_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, utf8_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, utf16_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, utf32_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, badrecord_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, copy_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, reuse_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, ensure_at_least_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, ensure_exactly_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, skip_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, get_tail_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, equal_colon_equal_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, signed_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, machine_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, avm_floatsize_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, close_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, closed_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, port_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, info_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, module_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, select_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, ready_input_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, ready_output_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, attributes_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, compile_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, exports_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, incomplete_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, kill_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, killed_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, links_atom, AtomTableNoOpts);

atom_table_ensure_atom(table, total_heap_size_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, atomvm_heap_growth_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, bounded_free_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, minimum_atom, AtomTableNoOpts);
atom_table_ensure_atom(table, fibonacci_atom, AtomTableNoOpts);

return decimals_index;
}
Expand All @@ -422,10 +422,10 @@ void test_atom_table()

assert(atom_table_get_index(table, "\x4" "ciao") == ATOM_TABLE_NOT_FOUND);

assert(atom_table_ensure_atom(table, "\x3" "bar") == 0);
assert(atom_table_ensure_atom(table, "\x4" "ciao") == 1);
assert(atom_table_ensure_atom(table, "\x3" "foo") == 2);
assert(atom_table_ensure_atom(table, "\x3" "foo") == 2);
assert(atom_table_ensure_atom(table, "\x3" "bar", AtomTableNoOpts) == 0);
assert(atom_table_ensure_atom(table, "\x4" "ciao", AtomTableNoOpts) == 1);
assert(atom_table_ensure_atom(table, "\x3" "foo", AtomTableNoOpts) == 2);
assert(atom_table_ensure_atom(table, "\x3" "foo", AtomTableNoOpts) == 2);

assert(atom_table_get_index(table, "\x4" "ciao") == 1);

Expand All @@ -434,7 +434,7 @@ void test_atom_table()
int decimals_index = insert_atoms_into_atom_table(table);

assert(atom_table_get_index(table, "\x8" "decimals") == decimals_index);
assert(atom_table_ensure_atom(table, "\x8" "decimals") == decimals_index);
assert(atom_table_ensure_atom(table, "\x8" "decimals", AtomTableNoOpts) == decimals_index);
}

int main(int argc, char **argv)
Expand Down

0 comments on commit f84455b

Please sign in to comment.