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); }
void os_link_runtime() { lispobj head; void *link_target = (void*)(intptr_t)LINKAGE_TABLE_SPACE_START; void *validated_end = link_target; lispobj symbol_name; char *namechars; boolean datap; void* result; int strict /* If in a cold core, fail early and often. */ = (SymbolValue(GC_INHIBIT, 0) & WIDETAG_MASK) == UNBOUND_MARKER_WIDETAG; int n = 0, m = 0; for (head = SymbolValue(REQUIRED_RUNTIME_C_SYMBOLS,0); head!=NIL; head = cdr(head), n++) { lispobj item = car(head); symbol_name = car(item); datap = (NIL!=(cdr(item))); namechars = (void*)(intptr_t)FOTHERPTR(symbol_name,vector).data; result = os_dlsym_default(namechars); odxprint(runtime_link, "linking %s => %p", namechars, result); if (link_target == validated_end) { validated_end += os_vm_page_size; #ifdef LISP_FEATURE_WIN32 os_validate_recommit(link_target,os_vm_page_size); #endif } if (result) { if (datap) arch_write_linkage_table_ref(link_target,result); else arch_write_linkage_table_jmp(link_target,result); } else { m++; if (strict) fprintf(stderr, "undefined foreign symbol in cold init: %s\n", namechars); } link_target = (void*)(((uintptr_t)link_target)+LINKAGE_TABLE_ENTRY_SIZE); } odxprint(runtime_link, "%d total symbols linked, %d undefined", n, m); if (strict && m) /* We could proceed, but rather than run into improperly * displayed internal errors, let's make ourselves heard right * here and now. */ lose("Undefined aliens in cold init."); }
void * os_dlsym_default(char *name) { void *frob = dlsym(RTLD_DEFAULT, name); odxprint(misc, "%p", frob); return frob; }
void map_gc_page() { odxprint(misc, "map_gc_page"); os_protect((void *) GC_SAFEPOINT_PAGE_ADDR, 4, OS_VM_PROT_READ | OS_VM_PROT_WRITE); }
void unmap_gc_page() { odxprint(misc, "unmap_gc_page"); os_protect((void *) GC_SAFEPOINT_PAGE_ADDR, 4, OS_VM_PROT_NONE); }
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(&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. */ void *stack_addr; size_t stack_size; #ifdef LISP_FEATURE_OPENBSD stack_t stack; pthread_stackseg_np(os, &stack); stack_size = stack.ss_size; stack_addr = (void*)((size_t)stack.ss_sp - stack_size); #elif defined LISP_FEATURE_SUNOS stack_t stack; thr_stksegment(&stack); stack_size = stack.ss_size; stack_addr = (void*)((size_t)stack.ss_sp - stack_size); #elif defined(LISP_FEATURE_DARWIN) stack_addr = pthread_get_stackaddr_np(os); stack_size = pthread_get_stacksize_np(os); #else pthread_attr_t attr; #ifdef LISP_FEATURE_FREEBSD pthread_attr_get_np(os, &attr); #else int pthread_getattr_np(pthread_t, pthread_attr_t *); pthread_getattr_np(os, &attr); #endif pthread_attr_getstack(&attr, &stack_addr, &stack_size); #endif 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); }