static void perform_thread_post_mortem(struct thread_post_mortem *post_mortem) { #ifdef CREATE_POST_MORTEM_THREAD pthread_detach(pthread_self()); #endif int result; if (post_mortem) { /* The thread may exit before pthread_create() has finished initialization and it may write into already unmapped memory. This lock doesn't actually need to protect anything, just to make sure that at least one call to pthread_create() has finished. Possible improvements: stash the address of the thread struct for which a pthread is being created and don't lock here if it's not the one being terminated. */ result = pthread_mutex_lock(&create_thread_lock); gc_assert(result == 0); result = pthread_mutex_unlock(&create_thread_lock); gc_assert(result == 0); if ((result = pthread_join(post_mortem->os_thread, NULL))) { lose("Error calling pthread_join in perform_thread_post_mortem:\n%s", strerror(result)); } if ((result = pthread_attr_destroy(post_mortem->os_attr))) { lose("Error calling pthread_attr_destroy in perform_thread_post_mortem:\n%s", strerror(result)); } os_invalidate(post_mortem->os_address, THREAD_STRUCT_SIZE); free(post_mortem); } }
void os_zero(os_vm_address_t addr, os_vm_size_t length) { os_vm_address_t block_start; os_vm_size_t block_size; #ifdef DEBUG fprintf(stderr,";;; os_zero: addr: 0x%08x, len: 0x%08x\n",addr,length); #endif block_start = os_round_up_to_page(addr); length -= block_start-addr; block_size = os_trunc_size_to_page(length); if (block_start > addr) bzero((char *)addr, block_start-addr); if (block_size < length) bzero((char *)block_start+block_size, length-block_size); if (block_size != 0) { /* Now deallocate and allocate the block so that it faults in * zero-filled. */ os_invalidate(block_start, block_size); addr = os_validate(NOT_MOVABLE, block_start, block_size); if (addr == NULL || addr != block_start) lose("os_zero: block moved! 0x%08x ==> 0x%08x\n", block_start, addr); } }
/* * If this feature is set, we are running on a stack managed by the OS, * and no fancy delays are required for anything. Just do it. */ static void schedule_thread_post_mortem(struct thread *corpse) { pthread_detach(pthread_self()); gc_assert(!pthread_attr_destroy(corpse->os_attr)); #if defined(LISP_FEATURE_WIN32) os_invalidate_free(corpse->os_address, THREAD_STRUCT_SIZE); #else os_invalidate(corpse->os_address, THREAD_STRUCT_SIZE); #endif }
static void perform_thread_post_mortem(struct thread_post_mortem *post_mortem) { #ifdef CREATE_POST_MORTEM_THREAD pthread_detach(pthread_self()); #endif int result; if (post_mortem) { if ((result = pthread_join(post_mortem->os_thread, NULL))) { lose("Error calling pthread_join in perform_thread_post_mortem:\n%s", strerror(result)); } if ((result = pthread_attr_destroy(post_mortem->os_attr))) { lose("Error calling pthread_attr_destroy in perform_thread_post_mortem:\n%s", strerror(result)); } os_invalidate(post_mortem->os_address, THREAD_STRUCT_SIZE); free(post_mortem); } }
void os_deallocate(os_vm_address_t addr, os_vm_size_t len) { os_invalidate(addr,len); }