55#include "wasm_c_api_internal.h"
66
77#include "bh_assert.h"
8+ #include "wasm_export.h"
89#include "wasm_memory.h"
910#if WASM_ENABLE_INTERP != 0
1011#include "wasm_runtime.h"
@@ -36,6 +37,13 @@ typedef struct wasm_module_ex_t {
3637 uint32 ref_count ;
3738} wasm_module_ex_t ;
3839
40+ #ifndef os_thread_local_attribute
41+ typedef struct thread_local_stores {
42+ korp_tid tid ;
43+ unsigned stores_num ;
44+ } thread_local_stores ;
45+ #endif
46+
3947static void
4048wasm_module_delete_internal (wasm_module_t * );
4149
@@ -281,24 +289,23 @@ static void
281289wasm_engine_delete_internal (wasm_engine_t * engine )
282290{
283291 if (engine ) {
284- if (engine -> stores ) {
285- bh_vector_destroy ((Vector * )engine -> stores );
286- wasm_runtime_free (engine -> stores );
287- }
288-
289292 /* clean all created wasm_module_t and their locks */
290- {
291- unsigned i ;
292- for (i = 0 ; i < engine -> modules .num_elems ; i ++ ) {
293- wasm_module_ex_t * module ;
294- if (bh_vector_get (& engine -> modules , i , & module )) {
295- os_mutex_destroy (& module -> lock );
296- wasm_runtime_free (module );
297- }
293+ unsigned i ;
294+
295+ for (i = 0 ; i < engine -> modules .num_elems ; i ++ ) {
296+ wasm_module_ex_t * module ;
297+ if (bh_vector_get (& engine -> modules , i , & module )) {
298+ os_mutex_destroy (& module -> lock );
299+ wasm_runtime_free (module );
298300 }
299- bh_vector_destroy (& engine -> modules );
300301 }
301302
303+ bh_vector_destroy (& engine -> modules );
304+
305+ #ifndef os_thread_local_attribute
306+ bh_vector_destroy (& engine -> stores_by_tid );
307+ #endif
308+
302309 wasm_runtime_free (engine );
303310 }
304311
@@ -360,12 +367,16 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
360367 goto failed ;
361368 }
362369
363- INIT_VEC (engine -> stores , wasm_store_vec_new_uninitialized , 1 );
364-
365370 if (!bh_vector_init (& engine -> modules , DEFAULT_VECTOR_INIT_SIZE ,
366371 sizeof (wasm_module_ex_t * ), true))
367372 goto failed ;
368373
374+ #ifndef os_thread_local_attribute
375+ if (!bh_vector_init (& engine -> stores_by_tid , DEFAULT_VECTOR_INIT_SIZE ,
376+ sizeof (thread_local_stores ), true))
377+ goto failed ;
378+ #endif
379+
369380 engine -> ref_count = 1 ;
370381
371382 WASM_C_DUMP_PROC_MEM ();
@@ -375,6 +386,10 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
375386
376387/* global engine instance */
377388static wasm_engine_t * singleton_engine = NULL ;
389+ #ifdef os_thread_local_attribute
390+ /* categorize wasm_store_t as threads*/
391+ static os_thread_local_attribute unsigned thread_local_stores_num = 0 ;
392+ #endif
378393#if defined(OS_THREAD_MUTEX_INITIALIZER )
379394/**
380395 * lock for the singleton_engine
@@ -449,25 +464,187 @@ wasm_engine_delete(wasm_engine_t *engine)
449464#endif
450465}
451466
467+ #ifndef os_thread_local_attribute
468+ static bool
469+ search_thread_local_store_num (Vector * stores_by_tid , korp_tid tid ,
470+ thread_local_stores * out_ts , unsigned * out_i )
471+ {
472+ unsigned i ;
473+
474+ for (i = 0 ; i < stores_by_tid -> num_elems ; i ++ ) {
475+ bool ret = bh_vector_get (stores_by_tid , i , out_ts );
476+ bh_assert (ret );
477+ (void )ret ;
478+
479+ if (out_ts -> tid == tid ) {
480+ * out_i = i ;
481+ return true;
482+ }
483+ }
484+
485+ return false;
486+ }
487+ #endif
488+
489+ static unsigned
490+ retrive_thread_local_store_num (Vector * stores_by_tid , korp_tid tid )
491+ {
492+ #ifndef os_thread_local_attribute
493+ unsigned i = 0 ;
494+ thread_local_stores ts = { 0 };
495+ unsigned ret = 0 ;
496+
497+ #if defined(OS_THREAD_MUTEX_INITIALIZER )
498+ os_mutex_lock (& engine_lock );
499+ #endif
500+
501+ if (search_thread_local_store_num (stores_by_tid , tid , & ts , & i ))
502+ ret = ts .stores_num ;
503+ else
504+ ret = 0 ;
505+
506+ #if defined(OS_THREAD_MUTEX_INITIALIZER )
507+ os_mutex_unlock (& engine_lock );
508+ #endif
509+
510+ return ret ;
511+ #else
512+ (void )stores_by_tid ;
513+ (void )tid ;
514+
515+ return thread_local_stores_num ;
516+ #endif
517+ }
518+
519+ static bool
520+ increase_thread_local_store_num (Vector * stores_by_tid , korp_tid tid )
521+ {
522+ #ifndef os_thread_local_attribute
523+ unsigned i = 0 ;
524+ thread_local_stores ts = { 0 };
525+ bool ret = false;
526+
527+ #if defined(OS_THREAD_MUTEX_INITIALIZER )
528+ os_mutex_lock (& engine_lock );
529+ #endif
530+
531+ if (search_thread_local_store_num (stores_by_tid , tid , & ts , & i )) {
532+ /* just in case if integer overflow */
533+ if (ts .stores_num + 1 < ts .stores_num ) {
534+ ret = false;
535+ }
536+ else {
537+ ts .stores_num ++ ;
538+ ret = bh_vector_set (stores_by_tid , i , & ts );
539+ bh_assert (ret );
540+ }
541+ }
542+ else {
543+ ts .tid = tid ;
544+ ts .stores_num = 1 ;
545+ ret = bh_vector_append (stores_by_tid , & ts );
546+ }
547+
548+ #if defined(OS_THREAD_MUTEX_INITIALIZER )
549+ os_mutex_unlock (& engine_lock );
550+ #endif
551+ return ret ;
552+ #else
553+ (void )stores_by_tid ;
554+ (void )tid ;
555+
556+ /* just in case if integer overflow */
557+ if (thread_local_stores_num + 1 < thread_local_stores_num )
558+ return false;
559+
560+ thread_local_stores_num ++ ;
561+ return true;
562+ #endif
563+ }
564+
565+ static bool
566+ decrease_thread_local_store_num (Vector * stores_by_tid , korp_tid tid )
567+ {
568+ #ifndef os_thread_local_attribute
569+ unsigned i = 0 ;
570+ thread_local_stores ts = { 0 };
571+ bool ret = false;
572+
573+ #if defined(OS_THREAD_MUTEX_INITIALIZER )
574+ os_mutex_lock (& engine_lock );
575+ #endif
576+
577+ ret = search_thread_local_store_num (stores_by_tid , tid , & ts , & i );
578+ bh_assert (ret );
579+
580+ /* just in case if integer overflow */
581+ if (ts .stores_num - 1 > ts .stores_num ) {
582+ ret = false;
583+ }
584+ else {
585+ ts .stores_num -- ;
586+ ret = bh_vector_set (stores_by_tid , i , & ts );
587+ bh_assert (ret );
588+ }
589+
590+ #if defined(OS_THREAD_MUTEX_INITIALIZER )
591+ os_mutex_unlock (& engine_lock );
592+ #endif
593+
594+ return ret ;
595+ #else
596+ (void )stores_by_tid ;
597+ (void )tid ;
598+
599+ /* just in case if integer overflow */
600+ if (thread_local_stores_num - 1 > thread_local_stores_num )
601+ return false;
602+
603+ thread_local_stores_num -- ;
604+ return true;
605+ #endif
606+ }
607+
452608wasm_store_t *
453609wasm_store_new (wasm_engine_t * engine )
454610{
455611 wasm_store_t * store = NULL ;
456612
457613 WASM_C_DUMP_PROC_MEM ();
458614
459- if (!engine || singleton_engine != engine ) {
615+ if (!engine || singleton_engine != engine )
460616 return NULL ;
461- }
462617
463- if (!wasm_runtime_init_thread_env ()) {
464- LOG_ERROR ("init thread environment failed" );
465- return NULL ;
618+ if (!retrive_thread_local_store_num (& engine -> stores_by_tid ,
619+ os_self_thread ())) {
620+ if (!wasm_runtime_init_thread_env ()) {
621+ LOG_ERROR ("init thread environment failed" );
622+ return NULL ;
623+ }
624+
625+ if (!increase_thread_local_store_num (& engine -> stores_by_tid ,
626+ os_self_thread ())) {
627+ wasm_runtime_destroy_thread_env ();
628+ return NULL ;
629+ }
630+
631+ if (!(store = malloc_internal (sizeof (wasm_store_t )))) {
632+ decrease_thread_local_store_num (& singleton_engine -> stores_by_tid ,
633+ os_self_thread ());
634+ wasm_runtime_destroy_thread_env ();
635+ return NULL ;
636+ }
466637 }
638+ else {
639+ if (!increase_thread_local_store_num (& engine -> stores_by_tid ,
640+ os_self_thread ()))
641+ return NULL ;
467642
468- if (!(store = malloc_internal (sizeof (wasm_store_t )))) {
469- wasm_runtime_destroy_thread_env ();
470- return NULL ;
643+ if (!(store = malloc_internal (sizeof (wasm_store_t )))) {
644+ decrease_thread_local_store_num (& singleton_engine -> stores_by_tid ,
645+ os_self_thread ());
646+ return NULL ;
647+ }
471648 }
472649
473650 /* new a vector, and new its data */
@@ -482,12 +659,6 @@ wasm_store_new(wasm_engine_t *engine)
482659 goto failed ;
483660 }
484661
485- /* append to a store list of engine */
486- if (!bh_vector_append ((Vector * )singleton_engine -> stores , & store )) {
487- LOG_DEBUG ("bh_vector_append failed" );
488- goto failed ;
489- }
490-
491662 WASM_C_DUMP_PROC_MEM ();
492663
493664 return store ;
@@ -511,7 +682,14 @@ wasm_store_delete(wasm_store_t *store)
511682 }
512683
513684 wasm_runtime_free (store );
514- wasm_runtime_destroy_thread_env ();
685+
686+ if (decrease_thread_local_store_num (& singleton_engine -> stores_by_tid ,
687+ os_self_thread ())) {
688+ if (!retrive_thread_local_store_num (& singleton_engine -> stores_by_tid ,
689+ os_self_thread ())) {
690+ wasm_runtime_destroy_thread_env ();
691+ }
692+ }
515693}
516694
517695/* Type Representations */
@@ -1681,10 +1859,8 @@ wasm_trap_new_internal(wasm_store_t *store,
16811859 uint32 i ;
16821860#endif
16831861
1684- if (!singleton_engine || !singleton_engine -> stores
1685- || !singleton_engine -> stores -> num_elems ) {
1862+ if (!singleton_engine )
16861863 return NULL ;
1687- }
16881864
16891865 if (!(trap = malloc_internal (sizeof (wasm_trap_t )))) {
16901866 return NULL ;
0 commit comments