+
+static void
+free_thread_stack_later(struct thread *thread_to_be_cleaned_up)
+{
+ struct freeable_stack *new_freeable_stack = 0;
+ if (thread_to_be_cleaned_up) {
+ new_freeable_stack = (struct freeable_stack *)
+ os_validate(0, sizeof(struct freeable_stack));
+ new_freeable_stack->os_thread = thread_to_be_cleaned_up->os_thread;
+ new_freeable_stack->stack = (os_vm_address_t)
+ thread_to_be_cleaned_up->control_stack_start;
+ }
+ new_freeable_stack = (struct freeable_stack *)
+ swap_lispobjs((lispobj *)(void *)&freeable_stack,
+ (lispobj)new_freeable_stack);
+ if (new_freeable_stack) {
+ FSHOW((stderr,"/reaping %lu\n", new_freeable_stack->os_thread));
+ /* Under NPTL pthread_join really waits until the thread
+ * exists and the stack can be safely freed. This is sadly not
+ * mandated by the pthread spec. */
+ gc_assert(pthread_join(new_freeable_stack->os_thread, NULL) == 0);
+ os_invalidate(new_freeable_stack->stack, THREAD_STRUCT_SIZE);
+ os_invalidate((os_vm_address_t) new_freeable_stack,
+ sizeof(struct freeable_stack));
+ }
+}
+
+/* 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
+ */