emnapi 0.33.1 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +43 -1
- package/README.md +93 -19
- package/dist/library_napi.js +1262 -425
- package/lib/wasm32/libdlmalloc-mt.a +0 -0
- package/lib/wasm32/libdlmalloc.a +0 -0
- package/lib/wasm32/libemmalloc-mt.a +0 -0
- package/lib/wasm32/libemnapi-basic-mt.a +0 -0
- package/lib/wasm32-emscripten/libemnapi-mt.a +0 -0
- package/lib/wasm32-wasi/libemnapi-basic-mt.a +0 -0
- package/package.json +1 -1
- package/src/malloc/dlmalloc/malloc.c +2 -2
- package/src/thread/async_worker_create.c +76 -0
- package/src/thread/async_worker_init.S +33 -0
- package/src/threadsafe_function.c +3 -4
- package/src/uv/threadpool.c +9 -3
|
Binary file
|
package/lib/wasm32/libdlmalloc.a
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -2859,7 +2859,7 @@ static size_t traverse_and_check(mstate m);
|
|
|
2859
2859
|
#define treebin_at(M,i) (&((M)->treebins[i]))
|
|
2860
2860
|
|
|
2861
2861
|
/* assign tree index for size S to variable I. Use x86 asm if possible */
|
|
2862
|
-
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
|
2862
|
+
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__) || defined(__wasm__))
|
|
2863
2863
|
#define compute_tree_index(S, I)\
|
|
2864
2864
|
{\
|
|
2865
2865
|
unsigned int X = S >> TREEBIN_SHIFT;\
|
|
@@ -2962,7 +2962,7 @@ static size_t traverse_and_check(mstate m);
|
|
|
2962
2962
|
|
|
2963
2963
|
/* index corresponding to given bit. Use x86 asm if possible */
|
|
2964
2964
|
|
|
2965
|
-
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
|
2965
|
+
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__) || defined(__wasm__))
|
|
2966
2966
|
#define compute_bit2idx(X, I)\
|
|
2967
2967
|
{\
|
|
2968
2968
|
unsigned int J;\
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
void* calloc(size_t n, size_t size);
|
|
5
|
+
|
|
6
|
+
extern unsigned char __heap_base;
|
|
7
|
+
extern unsigned char __data_end;
|
|
8
|
+
extern unsigned char __global_base;
|
|
9
|
+
extern __attribute__((__weak__)) unsigned char __stack_high;
|
|
10
|
+
extern __attribute__((__weak__)) unsigned char __stack_low;
|
|
11
|
+
|
|
12
|
+
#define ROUND_UP(x, ALIGNMENT) (((x)+ALIGNMENT-1)&-ALIGNMENT)
|
|
13
|
+
#define STACK_ALIGN 16
|
|
14
|
+
#define DEFAULT_STACK_MAX (8<<20)
|
|
15
|
+
|
|
16
|
+
struct worker_args {
|
|
17
|
+
void* stack_base;
|
|
18
|
+
void* tls_base;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
extern void __wasm_init_tls(void*);
|
|
22
|
+
|
|
23
|
+
void* __copy_tls(unsigned char *mem) {
|
|
24
|
+
size_t tls_align = __builtin_wasm_tls_align();
|
|
25
|
+
volatile void* tls_base = __builtin_wasm_tls_base();
|
|
26
|
+
mem += tls_align;
|
|
27
|
+
mem -= (uintptr_t)mem & (tls_align-1);
|
|
28
|
+
__wasm_init_tls(mem);
|
|
29
|
+
__asm__("local.get %0\n"
|
|
30
|
+
"global.set __tls_base\n"
|
|
31
|
+
:: "r"(tls_base));
|
|
32
|
+
return mem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
__attribute__((visibility("default")))
|
|
36
|
+
void* emnapi_async_worker_create() {
|
|
37
|
+
size_t args_size = sizeof(struct worker_args);
|
|
38
|
+
size_t size = args_size;
|
|
39
|
+
|
|
40
|
+
size_t tls_size = __builtin_wasm_tls_size();
|
|
41
|
+
|
|
42
|
+
size_t tls_block_size = 0;
|
|
43
|
+
if (tls_size) {
|
|
44
|
+
size_t tls_align = __builtin_wasm_tls_align();
|
|
45
|
+
tls_block_size = ROUND_UP(tls_size + tls_align - 1, tls_align);
|
|
46
|
+
size += tls_block_size;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ptrdiff_t stack_size = 0;
|
|
50
|
+
if (&__stack_high) {
|
|
51
|
+
stack_size = &__stack_high - &__stack_low;
|
|
52
|
+
} else {
|
|
53
|
+
unsigned char *sp;
|
|
54
|
+
__asm__(
|
|
55
|
+
".globaltype __stack_pointer, i32\n"
|
|
56
|
+
"global.get __stack_pointer\n"
|
|
57
|
+
"local.set %0\n"
|
|
58
|
+
: "=r"(sp));
|
|
59
|
+
stack_size = sp > &__global_base ? &__heap_base - &__data_end : (ptrdiff_t)&__global_base;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
stack_size = ROUND_UP(stack_size, STACK_ALIGN);
|
|
63
|
+
stack_size = stack_size < DEFAULT_STACK_MAX ? stack_size : DEFAULT_STACK_MAX;
|
|
64
|
+
size += stack_size;
|
|
65
|
+
|
|
66
|
+
void* block = calloc(1, size);
|
|
67
|
+
if (!block) return 0;
|
|
68
|
+
|
|
69
|
+
void* tls_base = tls_size ? __copy_tls(block + args_size) : 0;
|
|
70
|
+
|
|
71
|
+
struct worker_args* args = (struct worker_args*)block;
|
|
72
|
+
|
|
73
|
+
args->stack_base = block + args_size + tls_block_size + stack_size;
|
|
74
|
+
args->tls_base = tls_base;
|
|
75
|
+
return block;
|
|
76
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#ifdef __wasm64__
|
|
2
|
+
#define PTR i64
|
|
3
|
+
#else
|
|
4
|
+
#define PTR i32
|
|
5
|
+
#endif
|
|
6
|
+
|
|
7
|
+
.text
|
|
8
|
+
|
|
9
|
+
.export_name emnapi_async_worker_init, emnapi_async_worker_init
|
|
10
|
+
|
|
11
|
+
.globaltype __stack_pointer, PTR
|
|
12
|
+
.globaltype __tls_base, PTR
|
|
13
|
+
|
|
14
|
+
.hidden emnapi_async_worker_init
|
|
15
|
+
.globl emnapi_async_worker_init
|
|
16
|
+
.type emnapi_async_worker_init,@function
|
|
17
|
+
|
|
18
|
+
emnapi_async_worker_init:
|
|
19
|
+
.functype emnapi_async_worker_init (PTR) -> ()
|
|
20
|
+
|
|
21
|
+
local.get 0
|
|
22
|
+
PTR.load 0
|
|
23
|
+
global.set __stack_pointer
|
|
24
|
+
|
|
25
|
+
local.get 0
|
|
26
|
+
#ifdef __wasm64__
|
|
27
|
+
PTR.load 8
|
|
28
|
+
#else
|
|
29
|
+
PTR.load 4
|
|
30
|
+
#endif
|
|
31
|
+
global.set __tls_base
|
|
32
|
+
|
|
33
|
+
end_function
|
|
@@ -362,7 +362,7 @@ static void _emnapi_tsfn_send(napi_threadsafe_function func) {
|
|
|
362
362
|
if ((current_state & kDispatchRunning) == kDispatchRunning) {
|
|
363
363
|
return;
|
|
364
364
|
}
|
|
365
|
-
uv_async_send(&func->async);
|
|
365
|
+
CHECK_EQ(0, uv_async_send(&func->async));
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
// only main thread
|
|
@@ -373,7 +373,7 @@ static void _emnapi_tsfn_dispatch(napi_threadsafe_function func) {
|
|
|
373
373
|
// starvation. See `src/node_messaging.cc` for an inspiration.
|
|
374
374
|
unsigned int iterations_left = kMaxIterationCount;
|
|
375
375
|
while (has_more && --iterations_left != 0) {
|
|
376
|
-
func->dispatch_state
|
|
376
|
+
atomic_store(&func->dispatch_state, kDispatchRunning);
|
|
377
377
|
has_more = _emnapi_tsfn_dispatch_one(func);
|
|
378
378
|
|
|
379
379
|
// Send() was called while we were executing the JS function
|
|
@@ -409,7 +409,7 @@ napi_create_threadsafe_function(napi_env env,
|
|
|
409
409
|
napi_threadsafe_function* result) {
|
|
410
410
|
#if EMNAPI_HAVE_THREADS
|
|
411
411
|
CHECK_ENV(env);
|
|
412
|
-
|
|
412
|
+
CHECK_ARG(env, async_resource_name);
|
|
413
413
|
RETURN_STATUS_IF_FALSE(env, initial_thread_count > 0, napi_invalid_arg);
|
|
414
414
|
CHECK_ARG(env, result);
|
|
415
415
|
|
|
@@ -439,7 +439,6 @@ napi_create_threadsafe_function(napi_env env,
|
|
|
439
439
|
if (status != napi_ok) return status;
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
CHECK_ARG(env, async_resource_name);
|
|
443
442
|
status = napi_coerce_to_string(env, async_resource_name, &resource_name);
|
|
444
443
|
if (status != napi_ok) return status;
|
|
445
444
|
|
package/src/uv/threadpool.c
CHANGED
|
@@ -209,6 +209,7 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
|
|
|
209
209
|
// nthreads = 0;
|
|
210
210
|
// }
|
|
211
211
|
|
|
212
|
+
EMNAPI_EXTERN int _emnapi_async_work_pool_size();
|
|
212
213
|
|
|
213
214
|
static void init_threads(void) {
|
|
214
215
|
unsigned int i;
|
|
@@ -223,9 +224,14 @@ static void init_threads(void) {
|
|
|
223
224
|
nthreads = EMNAPI_WORKER_POOL_SIZE;
|
|
224
225
|
#else
|
|
225
226
|
nthreads = ARRAY_SIZE(default_threads);
|
|
226
|
-
|
|
227
|
-
if (
|
|
228
|
-
nthreads =
|
|
227
|
+
int async_work_pool_size = _emnapi_async_work_pool_size();
|
|
228
|
+
if (async_work_pool_size > 0) {
|
|
229
|
+
nthreads = (unsigned int) async_work_pool_size;
|
|
230
|
+
} else {
|
|
231
|
+
val = getenv("UV_THREADPOOL_SIZE");
|
|
232
|
+
if (val != NULL)
|
|
233
|
+
nthreads = atoi(val);
|
|
234
|
+
}
|
|
229
235
|
#endif
|
|
230
236
|
if (nthreads == 0)
|
|
231
237
|
nthreads = 1;
|