+#if defined LISP_FEATURE_SB_THREAD
+/* This is not needed unless #+SB-THREAD, as there's a trivial null
+ * unithread definition. */
+
+void mark_dead_threads()
+{
+ pid_t kid;
+ int status;
+ while(1) {
+ kid=waitpid(-1,&status,__WALL|WNOHANG);
+ if(kid<=0) break;
+ if(WIFEXITED(status) || WIFSIGNALED(status)) {
+ struct thread *th=find_thread_by_pid(kid);
+ if(th) th->state=STATE_DEAD;
+ }
+ }
+}
+
+void reap_dead_threads()
+{
+ struct thread *th,*next,*prev=0;
+ th=all_threads;
+ while(th) {
+ next=th->next;
+ if(th->state==STATE_DEAD) {
+ funcall1(SymbolFunction(HANDLE_THREAD_EXIT),make_fixnum(th->pid));
+#ifdef LISP_FEATURE_GENCGC
+ gc_alloc_update_page_tables(0, &th->alloc_region);
+#endif
+ get_spinlock(&all_threads_lock,th->pid);
+ if(prev) prev->next=next;
+ else all_threads=next;
+ release_spinlock(&all_threads_lock);
+ if(th->tls_cookie>=0) arch_os_thread_cleanup(th);
+ os_invalidate((os_vm_address_t) th->control_stack_start,
+ ((sizeof (lispobj))
+ * (th->control_stack_end-th->control_stack_start)) +
+ BINDING_STACK_SIZE+ALIEN_STACK_SIZE+dynamic_values_bytes+
+ 32*SIGSTKSZ);
+ } else
+ prev=th;
+ th=next;
+ }
+}
+