diff --git a/porting/linux/user/src/thread/pthread_create.c b/porting/linux/user/src/thread/pthread_create.c index c0fc725f5b180caa3bdccac5c2661ab1e69b0e1d..1c55f01d6716c5d691d32a22de6c6fcb4ecd2215 100644 --- a/porting/linux/user/src/thread/pthread_create.c +++ b/porting/linux/user/src/thread/pthread_create.c @@ -10,6 +10,7 @@ #include #include #include +#include pid_t getpid(void); @@ -287,6 +288,8 @@ struct start_args { void *start_arg; volatile int control; unsigned long sig_mask[_NSIG/8/sizeof(long)]; + + pthread_mutex_t startup_handshake_lock; }; #ifdef ENABLE_HWASAN @@ -297,7 +300,11 @@ static int start(void *p) #ifdef ENABLE_HWASAN __hwasan_thread_enter(); #endif + struct start_args *args = p; + + pthread_mutex_lock(&args->startup_handshake_lock); + int state = args->control; if (state) { if (a_cas(&args->control, 1, 2)==1) @@ -326,7 +333,11 @@ static int start_c11(void *p) #ifdef ENABLE_HWASAN __hwasan_thread_enter(); #endif + struct start_args *args = p; + + pthread_mutex_lock(&args->startup_handshake_lock); + int (*start)(void*) = (int(*)(void*)) args->start_func; __pthread_exit((void *)(uintptr_t)start(args->start_arg)); return 0; @@ -482,6 +493,11 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att ~(1UL<<((SIGCANCEL-1)%(8*sizeof(long)))); __tl_lock(); + + pthread_mutex_init(&args->startup_handshake_lock, NULL); + + pthread_mutex_lock(&args->startup_handshake_lock); + if (!libc.threads_minus_1++) libc.need_locks = 1; ret = __clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock); @@ -521,6 +537,9 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att } *res = new; + + pthread_mutex_unlock(&args->startup_handshake_lock); + return 0; fail: __release_ptc();