Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/pthread/threading_internal.h
6171 views
1
/*
2
* Copyright 2021 The Emscripten Authors. All rights reserved.
3
* Emscripten is available under two separate licenses, the MIT license and the
4
* University of Illinois/NCSA Open Source License. Both these licenses can be
5
* found in the LICENSE file.
6
*/
7
8
#pragma once
9
10
#include <pthread.h>
11
12
#define EM_THREAD_NAME_MAX 32
13
14
#define EM_THREAD_STATUS int
15
#define EM_THREAD_STATUS_NOTSTARTED 0
16
#define EM_THREAD_STATUS_RUNNING 1
17
#define EM_THREAD_STATUS_SLEEPING 2 // Performing an unconditional sleep (usleep, etc.)
18
#define EM_THREAD_STATUS_WAITFUTEX 3 // Waiting for an explicit low-level futex (emscripten_futex_wait)
19
#define EM_THREAD_STATUS_WAITMUTEX 4 // Waiting for a pthread_mutex_t
20
#define EM_THREAD_STATUS_WAITPROXY 5 // Waiting for a proxied operation to finish.
21
#define EM_THREAD_STATUS_FINISHED 6
22
#define EM_THREAD_STATUS_NUMFIELDS 7
23
24
typedef struct thread_profiler_block {
25
// One of THREAD_STATUS_*
26
_Atomic int threadStatus;
27
// Wallclock time denoting when the current thread state was entered in.
28
double currentStatusStartTime;
29
// Accumulated duration times denoting how much time has been spent in each
30
// state, in msecs.
31
double timeSpentInStatus[EM_THREAD_STATUS_NUMFIELDS];
32
// A human-readable name for this thread.
33
char name[EM_THREAD_NAME_MAX];
34
} thread_profiler_block;
35
36
// Called whenever a thread performs a blocking action (or calls sched_yield).
37
// This function takes care of running the event queue and other housekeeping
38
// tasks.
39
//
40
// If the caller already knows the current time it can pass it via the now
41
// argument. This can save _emscripten_check_timers from needing to call out to
42
// JS to get the current time. Passing 0 means that caller doesn't know the
43
// current time.
44
void _emscripten_yield(double now);
45
46
void _emscripten_init_main_thread_js(void* tb);
47
void _emscripten_thread_profiler_enable();
48
void _emscripten_thread_cleanup(pthread_t thread);
49
50
hidden void* _emscripten_tls_init(void);
51
hidden void _emscripten_tls_free(void);
52
53
// Marks the given thread as strongly referenced. This is used to prevent the
54
// Node.js application from exiting as long as there are strongly referenced
55
// threads still running. Normally you don't need to call this function, and
56
// the pthread behaviour will match native in that background threads won't
57
// keep runtime alive, but waiting for them via e.g. pthread_join will.
58
// However, this is useful for features like PROXY_TO_PTHREAD where we want to
59
// keep running as long as the detached pthread is.
60
void _emscripten_thread_set_strongref(pthread_t thread);
61
62
// Checks certain structural invariants. This allows us to detect when
63
// already-freed threads are used in some APIs. Technically this is undefined
64
// behaviour, but we have a couple of places where we add these checks so that
65
// we can pass more of the posixtest suite than vanilla musl.
66
int _emscripten_thread_is_valid(pthread_t thread);
67
68
void _emscripten_thread_exit_joinable(pthread_t thread);
69
void _emscripten_thread_exit(void* result);
70
void _emscripten_process_dlopen_queue(void);
71
72
#ifdef NDEBUG
73
#define emscripten_set_current_thread_status(newStatus)
74
#define emscripten_conditional_set_current_thread_status(expectedStatus, newStatus)
75
#else
76
// Allocate the thread profile block for the given thread.
77
void _emscripten_thread_profiler_init(pthread_t thread);
78
79
// Sets the profiler status of the calling thread. This is a no-op if thread
80
// profiling is not active.
81
// This is an internal function and generally not intended for user code.
82
// When thread profiler is not enabled (not building with --threadprofiler),
83
// this is a no-op.
84
void emscripten_set_current_thread_status(EM_THREAD_STATUS newStatus);
85
86
// Sets the profiler status of the calling thread, but only if it was in the
87
// expected status beforehand.
88
// This is an internal function and generally not intended for user code.
89
// When thread profiler is not enabled (not building with --threadprofiler),
90
// this is a no-op.
91
void emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS expectedStatus, EM_THREAD_STATUS newStatus);
92
#endif
93
94
int __pthread_kill_js(pthread_t t, int sig);
95
int __pthread_create_js(struct __pthread *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
96
int _emscripten_default_pthread_stack_size();
97
void __set_thread_state(pthread_t ptr, int is_main, int is_runtime, int can_block);
98
99
double _emscripten_receive_on_main_thread_js(int funcIndex, void* emAsmAddr, pthread_t callingThread, int numCallArgs, double* args, void* ctx, void* ctxArgs);
100
101
void _emscripten_run_js_on_main_thread_done(void* ctx, void* arg, double result);
102
103
// Return non-zero if the calling thread supports Atomic.wait (For example
104
// if called from the main browser thread, this function will return zero
105
// since blocking is not allowed there).
106
int _emscripten_thread_supports_atomics_wait(void);
107
108