static int initial_thread_trampoline(struct thread *th) { lispobj function; #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) lispobj *args = NULL; #endif #ifdef LISP_FEATURE_SB_THREAD pthread_setspecific(lisp_thread, (void *)1); #endif #if defined(THREADS_USING_GCSIGNAL) && (defined(LISP_FEATURE_PPC) || defined(LISP_FEATURE_ARM64)) /* SIG_STOP_FOR_GC defaults to blocked on PPC? */ unblock_gc_signals(0,0); #endif function = th->no_tls_value_marker; th->no_tls_value_marker = NO_TLS_VALUE_MARKER_WIDETAG; if(arch_os_thread_init(th)==0) return 1; link_thread(th); th->os_thread=thread_self(); #ifndef LISP_FEATURE_WIN32 protect_control_stack_hard_guard_page(1, NULL); #endif protect_binding_stack_hard_guard_page(1, NULL); protect_alien_stack_hard_guard_page(1, NULL); #ifndef LISP_FEATURE_WIN32 protect_control_stack_guard_page(1, NULL); #endif protect_binding_stack_guard_page(1, NULL); protect_alien_stack_guard_page(1, NULL); /* WIN32 has a special stack arrangment, calling * call_into_lisp_first_time will put the new stack in the middle * of the current stack */ #if !defined(LISP_FEATURE_WIN32) && (defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)) return call_into_lisp_first_time(function,args,0); #else return funcall0(function); #endif }
/* this is the first thing that runs in the child (which is why the * silly calling convention). Basically it calls the user's requested * lisp function after doing arch_os_thread_init and whatever other * bookkeeping needs to be done */ int new_thread_trampoline(struct thread *th) { int result; init_thread_data scribble; FSHOW((stderr,"/creating thread %lu\n", thread_self())); check_deferrables_blocked_or_lose(0); #ifndef LISP_FEATURE_SB_SAFEPOINT check_gc_signals_unblocked_or_lose(0); #endif lispobj function = th->no_tls_value_marker; th->no_tls_value_marker = NO_TLS_VALUE_MARKER_WIDETAG; init_new_thread(th, &scribble, 1); result = funcall0(function); undo_init_new_thread(th, &scribble); schedule_thread_post_mortem(th); FSHOW((stderr,"/exiting thread %lu\n", thread_self())); return result; }