+boolean create_os_thread(struct thread *th,os_thread_t *kid_tid)
+{
+ /* The new thread inherits the restrictive signal mask set here,
+ * and enables signals again when it is set up properly. */
+ pthread_attr_t attr;
+ sigset_t newset,oldset;
+ boolean r=1;
+ sigemptyset(&newset);
+ /* Blocking deferrable signals is enough, since gc_stop_the_world
+ * waits until the child leaves STATE_STARTING. And why not let gc
+ * proceed as soon as possible? */
+ sigaddset_deferrable(&newset);
+ thread_sigmask(SIG_BLOCK, &newset, &oldset);
+
+ if((pthread_attr_init(&attr)) ||
+ (pthread_attr_setstack(&attr,th->control_stack_start,
+ THREAD_CONTROL_STACK_SIZE-16)) ||
+ (pthread_create
+ (kid_tid,&attr,(void *(*)(void *))new_thread_trampoline,th)))
+ r=0;
+ thread_sigmask(SIG_SETMASK,&oldset,0);
+ return r;
+}
+
+struct thread *create_thread(lispobj initial_function) {
+ struct thread *th;
+ os_thread_t kid_tid=0;
+ boolean success;
+
+ if(linux_no_threads_p) return 0;
+
+ th=create_thread_struct(initial_function);
+ if(th==0) return 0;
+
+ /* we must not be interrupted here after a successful
+ * create_os_thread, because the kid will be waiting for its
+ * thread struct to be linked */
+ GET_ALL_THREADS_LOCK("create_thread")
+
+ success=create_os_thread(th,&kid_tid);
+ if (success)
+ link_thread(th,kid_tid);
+ else
+ free_thread_struct(th);
+
+ RELEASE_ALL_THREADS_LOCK("create_thread")
+
+ if (success)
+ return th;
+ else
+ return 0;