Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions src/libAtomVM/globalcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ GlobalContext *globalcontext_new(void)
#ifndef AVM_NO_SMP
glb->modules_lock = smp_rwlock_create();
if (IS_NULL_PTR(glb->modules_lock)) {
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand Down Expand Up @@ -140,7 +140,7 @@ GlobalContext *globalcontext_new(void)
#ifndef AVM_NO_SMP
smp_rwlock_destroy(glb->modules_lock);
#endif
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand All @@ -155,7 +155,7 @@ GlobalContext *globalcontext_new(void)
#ifndef AVM_NO_SMP
smp_rwlock_destroy(glb->modules_lock);
#endif
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand All @@ -171,7 +171,7 @@ GlobalContext *globalcontext_new(void)
#ifndef AVM_NO_SMP
smp_rwlock_destroy(glb->modules_lock);
#endif
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand All @@ -185,7 +185,7 @@ GlobalContext *globalcontext_new(void)
#ifndef AVM_NO_SMP
smp_rwlock_destroy(glb->modules_lock);
#endif
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand All @@ -199,7 +199,7 @@ GlobalContext *globalcontext_new(void)
#ifndef AVM_NO_SMP
smp_rwlock_destroy(glb->modules_lock);
#endif
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand All @@ -215,7 +215,7 @@ GlobalContext *globalcontext_new(void)
resource_type_destroy(glb->posix_fd_resource_type);
#endif
smp_rwlock_destroy(glb->modules_lock);
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand All @@ -227,7 +227,7 @@ GlobalContext *globalcontext_new(void)
resource_type_destroy(glb->posix_fd_resource_type);
#endif
smp_rwlock_destroy(glb->modules_lock);
free(glb->modules_table);
valueshashtable_destroy(glb->modules_table);
atom_table_destroy(glb->atom_table);
free(glb);
return NULL;
Expand Down Expand Up @@ -257,10 +257,24 @@ COLD_FUNC void globalcontext_destroy(GlobalContext *glb)
struct ListHead *item;
struct ListHead *tmp;

while (true) {
struct ListHead *processes = synclist_rdlock(&glb->processes_table);
struct ListHead *first = list_first(processes);
if (first == processes) {
synclist_unlock(&glb->processes_table);
break;
}
Context *ctx = GET_LIST_ENTRY(first, Context, processes_table_head);
synclist_unlock(&glb->processes_table);
context_destroy(ctx);
}

int module_index = glb->loaded_modules_count;
for (int i = 0; i < module_index; i++) {
module_destroy(glb->modules_by_index[i]);
}
free(glb->modules_by_index);
valueshashtable_destroy(glb->modules_table);

struct ListHead *open_avm_packs = synclist_nolock(&glb->avmpack_data);
MUTABLE_LIST_FOR_EACH (item, tmp, open_avm_packs) {
Expand Down Expand Up @@ -318,6 +332,8 @@ COLD_FUNC void globalcontext_destroy(GlobalContext *glb)
synclist_destroy(&glb->registered_processes);
synclist_destroy(&glb->processes_table);

atom_table_destroy(glb->atom_table);

free(glb);
}

Expand Down
17 changes: 17 additions & 0 deletions src/libAtomVM/valueshashtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,23 @@ struct ValuesHashTable *valueshashtable_new(void)
return htable;
}

void valueshashtable_destroy(struct ValuesHashTable *hash_table)
{
for (size_t i = 0; i < hash_table->capacity; i++) {
struct HNode *node = hash_table->buckets[i];
while (node) {
struct HNode *next = node->next;
free(node);
node = next;
}
}
#ifndef AVM_NO_SMP
smp_rwlock_destroy(hash_table->lock);
#endif
free(hash_table->buckets);
free(hash_table);
}

int valueshashtable_insert(struct ValuesHashTable *hash_table, uintptr_t key, uintptr_t value)
{
SMP_WRLOCK(hash_table);
Expand Down
1 change: 1 addition & 0 deletions src/libAtomVM/valueshashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct ValuesHashTable
};

struct ValuesHashTable *valueshashtable_new(void);
void valueshashtable_destroy(struct ValuesHashTable *hash_table);
int valueshashtable_insert(struct ValuesHashTable *hash_table, uintptr_t key, uintptr_t value);
uintptr_t valueshashtable_get_value(const struct ValuesHashTable *hash_table, uintptr_t key, uintptr_t default_value);
int valueshashtable_has_key(const struct ValuesHashTable *hash_table, uintptr_t key);
Expand Down
14 changes: 9 additions & 5 deletions src/platforms/esp32/components/avm_builtins/network_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,8 @@ static void start_network(Context *ctx, term pid, term ref, term config)
data->owner_process_id = term_to_local_process_id(pid);
data->ref_ticks = term_to_ref_ticks(ref);
data->managed = roaming;
struct ESP32PlatformData *platform = ctx->global->platform_data;
platform->network_driver_data = data;

esp_netif_t *sta_wifi_interface = NULL;
if ((sta_wifi_config != NULL) || (roaming)) {
Expand Down Expand Up @@ -1379,7 +1381,7 @@ static void start_network(Context *ctx, term pid, term ref, term config)
return;
}

static void stop_network(void)
static void stop_network(GlobalContext *global)
{
// Stop sntp (ignore OK, or not configured error)
esp_sntp_stop();
Expand Down Expand Up @@ -1412,6 +1414,10 @@ static void stop_network(void)
if (sta_wifi_interface != NULL) {
esp_netif_destroy_default_wifi(sta_wifi_interface);
}

struct ESP32PlatformData *platform = global->platform_data;
free(platform->network_driver_data);
platform->network_driver_data = NULL;
}

static void get_sta_rssi(Context *ctx, term pid, term ref)
Expand Down Expand Up @@ -1912,7 +1918,7 @@ static NativeHandlerResult consume_mailbox(Context *ctx)
break;
case NetworkStopCmd:
cmd_terminate = true;
stop_network();
stop_network(ctx->global);
break;
case NetworkScanCmd:
wifi_scan(ctx, pid, ref, config);
Expand Down Expand Up @@ -1994,12 +2000,10 @@ Context *network_driver_create_port(GlobalContext *global, term opts)

static void network_driver_destroy(GlobalContext *global)
{
UNUSED(global);

// Unregister the scan handler first, since stop_network() does not handle
// it and esp_wifi_stop() may post WIFI_EVENT_SCAN_DONE for an aborted scan.
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_SCAN_DONE, &scan_done_handler);
stop_network();
stop_network(global);
}

REGISTER_PORT_DRIVER(network, network_driver_init, network_driver_destroy, network_driver_create_port)
Expand Down
5 changes: 4 additions & 1 deletion src/platforms/esp32/components/avm_sys/include/esp32_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ struct ESP32PlatformData
struct SyncList sockets;
struct ListHead ready_connections;

// network_driver
void *network_driver_data;

#ifndef AVM_NO_SMP
Mutex *entropy_mutex;
#endif
Expand All @@ -89,7 +92,7 @@ struct ESP32PlatformData

extern QueueSetHandle_t event_set;
extern QueueHandle_t event_queue;
void esp32_sys_queue_init();
void esp32_sys_queue_init(void);

void socket_init(Context *ctx, term opts);

Expand Down
7 changes: 6 additions & 1 deletion src/platforms/esp32/components/avm_sys/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,12 @@ static const char *const revision_atom = "\x8" "revision";
QueueHandle_t event_queue = NULL;
QueueSetHandle_t event_set = NULL;

void esp32_sys_queue_init()
void esp32_sys_queue_init(void)
{
if (event_set != NULL) {
return;
}

event_set = xQueueCreateSet(EVENT_QUEUE_LEN * 4);
event_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(void *));
xQueueAddToSet(event_queue, event_set);
Expand Down Expand Up @@ -230,6 +234,7 @@ void sys_init_platform(GlobalContext *glb)
glb->platform_data = platform;
platform->select_thread_exit = false;
platform->select_events_poll_count = -1;
platform->network_driver_data = NULL;
esp_vfs_eventfd_config_t eventfd_config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
esp_err_t err = esp_vfs_eventfd_register(&eventfd_config);
if (err == ESP_OK) {
Expand Down
22 changes: 20 additions & 2 deletions src/platforms/esp32/test/main/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,28 @@ static void eth_stop(esp_netif_t *eth_netif)
}
#endif

term avm_test_case(const char *test_module)
static void prepare_event_queue(void)
{
esp32_sys_queue_init();

QueueSetMemberHandle_t source;
while ((source = xQueueSelectFromSet(event_set, 0)) != NULL) {
if (UNLIKELY(source != event_queue)) {
fprintf(stderr, "Stale member in ESP32 event queue set.\n");
AVM_ABORT();
}

void *ignored;
if (UNLIKELY(xQueueReceive(event_queue, &ignored, 0) != pdTRUE)) {
AVM_ABORT();
}
}
}

term avm_test_case(const char *test_module)
{
prepare_event_queue();

GlobalContext *glb = globalcontext_new();
TEST_ASSERT(glb != NULL);

Expand Down Expand Up @@ -183,7 +201,7 @@ term avm_test_case(const char *test_module)
#ifndef AVM_NO_JIT
TEST_CASE("test_jit_compile", "[test_run]")
{
esp32_sys_queue_init();
prepare_event_queue();

GlobalContext *glb = globalcontext_new();
TEST_ASSERT(glb != NULL);
Expand Down
2 changes: 2 additions & 0 deletions tests/test-structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ void test_valueshashtable(void)
assert(valueshashtable_get_value(htable, 0xBBDDBBDD + i, 0xCAFEBABE) == 0xEEFFEEFFL + i);
assert(valueshashtable_get_value(htable, 0xABDDBBDD + i, 0xCAFEBABE) == 0xCAFEBABE);
}

valueshashtable_destroy(htable);
}

atom_index_t insert_atoms_into_atom_table(struct AtomTable *table)
Expand Down
Loading