| /* |
| * Copyright 2021 The Emscripten Authors. All rights reserved. |
| * Emscripten is available under two separate licenses, the MIT license and the |
| * University of Illinois/NCSA Open Source License. Both these licenses can be |
| * found in the LICENSE file. |
| */ |
| |
| #pragma once |
| |
| typedef union em_variant_val |
| { |
| int i; |
| int64_t i64; |
| float f; |
| double d; |
| void *vp; |
| char *cp; |
| } em_variant_val; |
| |
| // Proxied C/C++ functions support at most this many arguments. Dispatch is |
| // static/strongly typed by signature. |
| #define EM_QUEUED_CALL_MAX_ARGS 11 |
| typedef struct em_queued_call |
| { |
| int functionEnum; |
| void *functionPtr; |
| _Atomic uint32_t operationDone; |
| em_variant_val args[EM_QUEUED_JS_CALL_MAX_ARGS]; |
| em_variant_val returnValue; |
| |
| // An optional pointer to a secondary data block that should be free()d when |
| // this queued call is freed. |
| void *satelliteData; |
| |
| // If true, the caller has "detached" itself from this call object and the |
| // Emscripten main runtime thread should free up this em_queued_call object |
| // after it has been executed. If false, the caller is in control of the |
| // memory. |
| int calleeDelete; |
| } em_queued_call; |
| |
| typedef void (*em_func_v)(void); |
| typedef void (*em_func_vi)(int); |
| typedef void (*em_func_vf)(float); |
| typedef void (*em_func_vii)(int, int); |
| typedef void (*em_func_vif)(int, float); |
| typedef void (*em_func_vff)(float, float); |
| typedef void (*em_func_viii)(int, int, int); |
| typedef void (*em_func_viif)(int, int, float); |
| typedef void (*em_func_viff)(int, float, float); |
| typedef void (*em_func_vfff)(float, float, float); |
| typedef void (*em_func_viiii)(int, int, int, int); |
| typedef void (*em_func_viifi)(int, int, float, int); |
| typedef void (*em_func_vifff)(int, float, float, float); |
| typedef void (*em_func_vffff)(float, float, float, float); |
| typedef void (*em_func_viiiii)(int, int, int, int, int); |
| typedef void (*em_func_viffff)(int, float, float, float, float); |
| typedef void (*em_func_viiiiii)(int, int, int, int, int, int); |
| typedef void (*em_func_viiiiiii)(int, int, int, int, int, int, int); |
| typedef void (*em_func_viiiiiiii)(int, int, int, int, int, int, int, int); |
| typedef void (*em_func_viiiiiiiii)(int, int, int, int, int, int, int, int, int); |
| typedef void (*em_func_viiiiiiiiii)(int, int, int, int, int, int, int, int, int, int); |
| typedef void (*em_func_viiiiiiiiiii)(int, int, int, int, int, int, int, int, int, int, int); |
| typedef int (*em_func_i)(void); |
| typedef int (*em_func_ii)(int); |
| typedef int (*em_func_iii)(int, int); |
| typedef int (*em_func_iiii)(int, int, int); |
| typedef int (*em_func_iiiii)(int, int, int, int); |
| typedef int (*em_func_iiiiii)(int, int, int, int, int); |
| typedef int (*em_func_iiiiiii)(int, int, int, int, int, int); |
| typedef int (*em_func_iiiiiiii)(int, int, int, int, int, int, int); |
| typedef int (*em_func_iiiiiiiii)(int, int, int, int, int, int, int, int); |
| typedef int (*em_func_iiiiiiiiii)(int, int, int, int, int, int, int, int, int); |
| |
| #define EM_THREAD_NAME_MAX 32 |
| |
| #define EM_THREAD_STATUS int |
| #define EM_THREAD_STATUS_NOTSTARTED 0 |
| #define EM_THREAD_STATUS_RUNNING 1 |
| #define EM_THREAD_STATUS_SLEEPING 2 // Performing an unconditional sleep (usleep, etc.) |
| #define EM_THREAD_STATUS_WAITFUTEX 3 // Waiting for an explicit low-level futex (emscripten_futex_wait) |
| #define EM_THREAD_STATUS_WAITMUTEX 4 // Waiting for a pthread_mutex_t |
| #define EM_THREAD_STATUS_WAITPROXY 5 // Waiting for a proxied operation to finish. |
| #define EM_THREAD_STATUS_FINISHED 6 |
| #define EM_THREAD_STATUS_NUMFIELDS 7 |
| |
| typedef struct thread_profiler_block { |
| // One of THREAD_STATUS_* |
| _Atomic int threadStatus; |
| // Wallclock time denoting when the current thread state was entered in. |
| double currentStatusStartTime; |
| // Accumulated duration times denoting how much time has been spent in each |
| // state, in msecs. |
| double timeSpentInStatus[EM_THREAD_STATUS_NUMFIELDS]; |
| // A human-readable name for this thread. |
| char name[EM_THREAD_NAME_MAX]; |
| } thread_profiler_block; |
| |
| void __emscripten_init_main_thread_js(void* tb); |
| void _emscripten_thread_profiler_enable(); |
| void __emscripten_thread_cleanup(pthread_t thread); |
| |
| hidden void* _emscripten_tls_init(void); |
| hidden void _emscripten_tls_free(void); |
| |
| // Checks certain structural invariants. This allows us to detect when |
| // already-freed threads are used in some APIs. Technically this is undefined |
| // behaviour, but we have a couple of places where we add these checks so that |
| // we can pass more of the posixtest suite that vanilla musl. |
| int _emscripten_thread_is_valid(pthread_t thread); |
| |
| #ifdef NDEBUG |
| #define emscripten_set_current_thread_status(newStatus) |
| #define emscripten_conditional_set_current_thread_status(expectedStatus, newStatus) |
| #else |
| // Allocate the thread profile block for the given thread. |
| void _emscripten_thread_profiler_init(pthread_t thread); |
| |
| // Sets the profiler status of the calling thread. This is a no-op if thread |
| // profiling is not active. |
| // This is an internal function and generally not intended for user code. |
| // When thread profiler is not enabled (not building with --threadprofiler), |
| // this is a no-op. |
| void emscripten_set_current_thread_status(EM_THREAD_STATUS newStatus); |
| |
| // Sets the profiler status of the calling thread, but only if it was in the |
| // expected status beforehand. |
| // This is an internal function and generally not intended for user code. |
| // When thread profiler is not enabled (not building with --threadprofiler), |
| // this is a no-op. |
| void emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS expectedStatus, EM_THREAD_STATUS newStatus); |
| #endif |