+# ifdef LISP_FEATURE_SB_SAFEPOINT
+static struct thread *create_thread_struct(lispobj);
+
+void
+attach_os_thread(init_thread_data *scribble)
+{
+ os_thread_t os = pthread_self();
+ odxprint(misc, "attach_os_thread: attaching to %p", os);
+
+ struct thread *th = create_thread_struct(NIL);
+ block_deferrable_signals(0, &scribble->oldset);
+ th->no_tls_value_marker = NO_TLS_VALUE_MARKER_WIDETAG;
+ /* We don't actually want a pthread_attr here, but rather than add
+ * `if's to the post-mostem, let's just keep that code happy by
+ * keeping it initialized: */
+ pthread_attr_init(th->os_attr);
+
+#ifndef LISP_FEATURE_WIN32
+ /* On windows, arch_os_thread_init will take care of finding the
+ * stack. */
+ pthread_attr_t attr;
+ int pthread_getattr_np(pthread_t, pthread_attr_t *);
+ pthread_getattr_np(os, &attr);
+ void *stack_addr;
+ size_t stack_size;
+ pthread_attr_getstack(&attr, &stack_addr, &stack_size);
+ th->control_stack_start = stack_addr;
+ th->control_stack_end = (void *) (((uintptr_t) stack_addr) + stack_size);
+#endif
+
+ init_new_thread(th, scribble, 0);
+
+ /* We will be calling into Lisp soon, and the functions being called
+ * recklessly ignore the comment in target-thread which says that we
+ * must be careful to not cause GC while initializing a new thread.
+ * Since we first need to create a fresh thread object, it's really
+ * tempting to just perform such unsafe allocation though. So let's
+ * at least try to suppress GC before consing, and hope that it
+ * works: */
+ bind_variable(GC_INHIBIT, T, th);
+
+ uword_t stacksize
+ = (uword_t) th->control_stack_end - (uword_t) th->control_stack_start;
+ odxprint(misc, "attach_os_thread: attached %p as %p (0x%lx bytes stack)",
+ os, th, (long) stacksize);
+}
+
+void
+detach_os_thread(init_thread_data *scribble)
+{
+ struct thread *th = arch_os_get_current_thread();
+ odxprint(misc, "detach_os_thread: detaching");
+
+ undo_init_new_thread(th, scribble);
+
+ odxprint(misc, "deattach_os_thread: detached");
+ pthread_setspecific(lisp_thread, (void *)0);
+ thread_sigmask(SIG_SETMASK, &scribble->oldset, 0);
+}
+# endif /* safepoint */
+