- 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 %p\n", (void*) 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));
+ struct thread_post_mortem *post_mortem = NULL;
+ if (corpse) {
+ post_mortem = plan_thread_post_mortem(corpse);
+
+#ifdef DELAY_THREAD_POST_MORTEM
+ pthread_mutex_lock(&thread_post_mortem_lock);
+ /* First stick the new post mortem to the end of the queue. */
+ if (pending_thread_post_mortem) {
+ struct thread_post_mortem *next = pending_thread_post_mortem;
+ while (next->next) {
+ next = next->next;
+ }
+ next->next = post_mortem;
+ } else {
+ pending_thread_post_mortem = post_mortem;
+ }
+ /* Then, if there are enough things in the queue, clean up one
+ * from the head -- or increment the count, and null out the
+ * post_mortem we have. */
+ if (pending_thread_post_mortem_count > DELAY_THREAD_POST_MORTEM) {
+ post_mortem = pending_thread_post_mortem;
+ pending_thread_post_mortem = post_mortem->next;
+ } else {
+ pending_thread_post_mortem_count++;
+ post_mortem = NULL;
+ }
+ pthread_mutex_unlock(&thread_post_mortem_lock);
+ /* Finally run, the cleanup, if any. */
+ perform_thread_post_mortem(post_mortem);
+#elif defined(CREATE_POST_MORTEM_THREAD)
+ gc_assert(!pthread_create(&thread, NULL, perform_thread_post_mortem, post_mortem));
+#else
+ post_mortem = (struct thread_post_mortem *)
+ swap_lispobjs((lispobj *)(void *)&pending_thread_post_mortem,
+ (lispobj)post_mortem);
+ perform_thread_post_mortem(post_mortem);
+#endif