p->__cleanup_stack = NULL;
p->tl_join_ctx = NULL;
p->tl_exit_gate = MACH_PORT_NULL;
- p->tsd[__TSD_SEMAPHORE_CACHE] = (void*)SEMAPHORE_NULL;
+ p->tsd[__TSD_SEMAPHORE_CACHE] = (void*)(uintptr_t)SEMAPHORE_NULL;
p->tsd[__TSD_MACH_SPECIAL_REPLY] = 0;
p->cancel_state |= _PTHREAD_CANCEL_INITIALIZED;
_pthread_introspection_thread_start(p);
}
+PTHREAD_NOEXPORT
+void
+_pthread_main_thread_postfork_init(pthread_t p)
+{
+ _pthread_main_thread_init(p);
+ _pthread_set_self_internal(p, false);
+}
+
int
sched_yield(void)
{
pthread_globals_t globals = _pthread_globals();
_PTHREAD_LOCK_INIT(globals->psaved_self_global_lock);
__is_threaded = 0;
- _pthread_main_thread_init(globals->psaved_self);
+ _pthread_main_thread_postfork_init(globals->psaved_self);
struct _pthread_registration_data registration_data;
_pthread_bsdthread_init(®istration_data);
#include <pthread.h>
#include <pthread/private.h>
#include <dispatch/dispatch.h>
+#include <sys/wait.h>
+#include <stdlib.h>
#include "darwintest_defaults.h"
dispatch_async(dq, ^{ do_test(NULL); });
dispatch_sync(dq, ^{});
}
+
+T_DECL(pthread_threadid_fork, "pthread_threadid_np post-fork test")
+{
+ uint64_t tid = __thread_selfid();
+ T_ASSERT_NE(tid, (uint64_t)0, "__thread_selfid()");
+
+ uint64_t ptid = 0;
+ T_ASSERT_POSIX_ZERO(pthread_threadid_np(NULL, &ptid), NULL);
+ T_ASSERT_EQ(ptid, tid, NULL);
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ // child
+ uint64_t ntid = __thread_selfid();
+ if (ntid == tid) {
+ T_LOG("FAIL: forked child tid is equal to parent tid");
+ exit(1);
+ }
+
+ uint64_t nptid = 0;
+ if (pthread_threadid_np(NULL, &nptid) != 0) {
+ T_LOG("FAIL: pthread_threadid_np: %d", errno);
+ exit(1);
+ }
+
+ if (nptid != ntid) {
+ T_LOG("FAIL: pthread_threadid_np == tid (expected: %lld == %lld)",
+ nptid, ntid);
+ exit(1);
+ }
+ exit(0);
+ } else {
+ int status;
+ T_ASSERT_EQ(waitpid(pid, &status, 0), pid, NULL);
+ int exitstatus = WEXITSTATUS(status);
+ T_ASSERT_EQ(exitstatus, 0, NULL);
+ }
+}