Path: blob/main/system/lib/pthread/threading_internal.h
6171 views
/*1* Copyright 2021 The Emscripten Authors. All rights reserved.2* Emscripten is available under two separate licenses, the MIT license and the3* University of Illinois/NCSA Open Source License. Both these licenses can be4* found in the LICENSE file.5*/67#pragma once89#include <pthread.h>1011#define EM_THREAD_NAME_MAX 321213#define EM_THREAD_STATUS int14#define EM_THREAD_STATUS_NOTSTARTED 015#define EM_THREAD_STATUS_RUNNING 116#define EM_THREAD_STATUS_SLEEPING 2 // Performing an unconditional sleep (usleep, etc.)17#define EM_THREAD_STATUS_WAITFUTEX 3 // Waiting for an explicit low-level futex (emscripten_futex_wait)18#define EM_THREAD_STATUS_WAITMUTEX 4 // Waiting for a pthread_mutex_t19#define EM_THREAD_STATUS_WAITPROXY 5 // Waiting for a proxied operation to finish.20#define EM_THREAD_STATUS_FINISHED 621#define EM_THREAD_STATUS_NUMFIELDS 72223typedef struct thread_profiler_block {24// One of THREAD_STATUS_*25_Atomic int threadStatus;26// Wallclock time denoting when the current thread state was entered in.27double currentStatusStartTime;28// Accumulated duration times denoting how much time has been spent in each29// state, in msecs.30double timeSpentInStatus[EM_THREAD_STATUS_NUMFIELDS];31// A human-readable name for this thread.32char name[EM_THREAD_NAME_MAX];33} thread_profiler_block;3435// Called whenever a thread performs a blocking action (or calls sched_yield).36// This function takes care of running the event queue and other housekeeping37// tasks.38//39// If the caller already knows the current time it can pass it via the now40// argument. This can save _emscripten_check_timers from needing to call out to41// JS to get the current time. Passing 0 means that caller doesn't know the42// current time.43void _emscripten_yield(double now);4445void _emscripten_init_main_thread_js(void* tb);46void _emscripten_thread_profiler_enable();47void _emscripten_thread_cleanup(pthread_t thread);4849hidden void* _emscripten_tls_init(void);50hidden void _emscripten_tls_free(void);5152// Marks the given thread as strongly referenced. This is used to prevent the53// Node.js application from exiting as long as there are strongly referenced54// threads still running. Normally you don't need to call this function, and55// the pthread behaviour will match native in that background threads won't56// keep runtime alive, but waiting for them via e.g. pthread_join will.57// However, this is useful for features like PROXY_TO_PTHREAD where we want to58// keep running as long as the detached pthread is.59void _emscripten_thread_set_strongref(pthread_t thread);6061// Checks certain structural invariants. This allows us to detect when62// already-freed threads are used in some APIs. Technically this is undefined63// behaviour, but we have a couple of places where we add these checks so that64// we can pass more of the posixtest suite than vanilla musl.65int _emscripten_thread_is_valid(pthread_t thread);6667void _emscripten_thread_exit_joinable(pthread_t thread);68void _emscripten_thread_exit(void* result);69void _emscripten_process_dlopen_queue(void);7071#ifdef NDEBUG72#define emscripten_set_current_thread_status(newStatus)73#define emscripten_conditional_set_current_thread_status(expectedStatus, newStatus)74#else75// Allocate the thread profile block for the given thread.76void _emscripten_thread_profiler_init(pthread_t thread);7778// Sets the profiler status of the calling thread. This is a no-op if thread79// profiling is not active.80// This is an internal function and generally not intended for user code.81// When thread profiler is not enabled (not building with --threadprofiler),82// this is a no-op.83void emscripten_set_current_thread_status(EM_THREAD_STATUS newStatus);8485// Sets the profiler status of the calling thread, but only if it was in the86// expected status beforehand.87// This is an internal function and generally not intended for user code.88// When thread profiler is not enabled (not building with --threadprofiler),89// this is a no-op.90void emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS expectedStatus, EM_THREAD_STATUS newStatus);91#endif9293int __pthread_kill_js(pthread_t t, int sig);94int __pthread_create_js(struct __pthread *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);95int _emscripten_default_pthread_stack_size();96void __set_thread_state(pthread_t ptr, int is_main, int is_runtime, int can_block);9798double _emscripten_receive_on_main_thread_js(int funcIndex, void* emAsmAddr, pthread_t callingThread, int numCallArgs, double* args, void* ctx, void* ctxArgs);99100void _emscripten_run_js_on_main_thread_done(void* ctx, void* arg, double result);101102// Return non-zero if the calling thread supports Atomic.wait (For example103// if called from the main browser thread, this function will return zero104// since blocking is not allowed there).105int _emscripten_thread_supports_atomics_wait(void);106107108