MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / __pthread_create

Function __pthread_create

system/lib/pthread/pthread_create.c:107–270  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

105#define ROUND_UP(x, ALIGNMENT) (((x)+ALIGNMENT-1)&-ALIGNMENT)
106
107int __pthread_create(pthread_t* restrict res,
108 const pthread_attr_t* restrict attrp,
109 void* (*entry)(void*),
110 void* restrict arg) {
111 // Note on LSAN: lsan intercepts/wraps calls to pthread_create so any
112 // allocations we do here should not be considered leaks.
113 // See: lsan_interceptors.cpp.
114 if (!res) {
115 return EINVAL;
116 }
117
118 if (!libc.threaded) {
119 for (FILE *f=*__ofl_lock(); f; f=f->next)
120 init_file_lock(f);
121 __ofl_unlock();
122 init_file_lock(__stdin_used);
123 init_file_lock(__stdout_used);
124 init_file_lock(__stderr_used);
125 libc.threaded = 1;
126 }
127
128 pthread_attr_t attr = { 0 };
129 if (attrp && attrp != __ATTRP_C11_THREAD) attr = *attrp;
130 if (!attr._a_stacksize) {
131 attr._a_stacksize = __default_stacksize;
132 }
133
134 // Allocate memory for new thread. The layout of the thread block is
135 // as follows. From low to high address:
136 //
137 // 1. pthread struct (sizeof struct pthread)
138 // 2. tls data (__builtin_wasm_tls_size())
139 // 3. tsd pointers (__pthread_tsd_size)
140 // 4. stack (__default_stacksize AKA -sDEFAULT_PTHREAD_STACK_SIZE)
141 size_t size = sizeof(struct pthread);
142 if (__builtin_wasm_tls_size()) {
143 size += __builtin_wasm_tls_size() + __builtin_wasm_tls_align() - 1;
144 }
145 size += __pthread_tsd_size + TSD_ALIGN - 1;
146 size_t zero_size = size;
147 if (!attr._a_stackaddr) {
148 size += attr._a_stacksize + STACK_ALIGN - 1;
149 }
150
151 // Allocate all the data for the new thread and zero-initialize all parts
152 // except for the stack.
153 unsigned char* block = emscripten_builtin_malloc(size);
154 memset(block, 0, zero_size);
155
156 uintptr_t offset = (uintptr_t)block;
157
158 // 1. pthread struct
159 struct pthread *new = (struct pthread*)offset;
160 offset += sizeof(struct pthread);
161
162 new->map_base = block;
163 new->map_size = size;
164

Callers

nothing calls this directly

Calls 12

__ofl_lockFunction · 0.85
__ofl_unlockFunction · 0.85
memsetFunction · 0.85
_emscripten_get_next_tidFunction · 0.85
__atomic_store_nFunction · 0.85
init_file_lockFunction · 0.70
__tl_lockFunction · 0.70
__tl_unlockFunction · 0.70
assertFunction · 0.50
dbgFunction · 0.50

Tested by

no test coverage detected