void* OSThread::_Entry(void *inThread) //static #endif { OSThread* theThread = (OSThread*)inThread; #ifdef __Win32__ BOOL theErr = ::TlsSetValue(sThreadStorageIndex, theThread); Assert(theErr == TRUE); #elif __PTHREADS__ theThread->fThreadID = (pthread_t)pthread_self(); pthread_setspecific(OSThread::gMainKey, theThread); #else theThread->fThreadID = (UInt32)cthread_self(); cthread_set_data(cthread_self(), (any_t)theThread); #endif theThread->SwitchPersonality(); // // Run the thread theThread->Entry(); #ifdef __Win32__ return 0; #else return NULL; #endif }
static void fault_handler (int sig, long int sigcode, struct sigcontext *scp) { jmp_buf *env = cthread_data (cthread_self ()); error_t err; #ifndef NDEBUG if (!env) { error (0, 0, "BUG: unexpected fault on disk image (%d, %#lx) in [%#lx,%#lx)" " eip %#zx err %#x", sig, sigcode, preemptor.first, preemptor.last, scp->sc_pc, scp->sc_error); assert (scp->sc_error == EKERN_MEMORY_ERROR); err = pager_get_error (diskfs_disk_pager, sigcode); assert (err); assert_perror (err); } #endif /* Clear the record, since the faulting thread will not. */ cthread_set_data (cthread_self (), 0); /* Fetch the error code from the pager. */ assert (scp->sc_error == EKERN_MEMORY_ERROR); err = pager_get_error (diskfs_disk_pager, sigcode); assert (err); /* Make `diskfault_catch' return the error code. */ longjmp (*env, err); }
void default_pager_thread( void *arg) { default_pager_thread_t *dpt; mach_port_t pset; kern_return_t kr; static char here[] = "default_pager_thread"; mach_msg_options_t server_options; dpt = (default_pager_thread_t *)arg; cthread_set_data(cthread_self(), (char *) dpt); /* * Threads handling external objects cannot have * privileges. Otherwise a burst of data-requests for an * external object could empty the free-page queue, * because the fault code only reserves real pages for * requests sent to internal objects. */ if (dpt->dpt_internal) { default_pager_thread_privileges(); pset = default_pager_internal_set; } else { pset = default_pager_external_set; } dpt->dpt_initialized_p = TRUE; /* Ready for requests. */ server_options = MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SEQNO); for (;;) { kr = mach_msg_server(default_pager_demux_object, default_pager_msg_size, pset, server_options); Panic("mach_msg_server failed"); } }
/* * Initialize and Run the default pager */ void default_pager(void) { int i, id; static char here[] = "default_pager"; mach_msg_options_t server_options; default_pager_thread_t dpt; default_pager_thread_t **dpt_array; default_pager_thread_privileges(); /* * Wire down code, data, stack */ wire_all_memory(); /* * Give me space for the thread array and zero it. */ i = default_pager_internal_count + default_pager_external_count + 1; dpt_array = (default_pager_thread_t **) kalloc(i * sizeof(default_pager_thread_t *)); memset(dpt_array, 0, i * sizeof(default_pager_thread_t *)); /* Setup my thread structure. */ id = 0; dpt.dpt_thread = cthread_self(); dpt.dpt_buffer = 0; dpt.dpt_internal = FALSE; dpt.dpt_id = id++; dpt.dpt_initialized_p = TRUE; cthread_set_data(cthread_self(), (char *) &dpt); dpt_array[0] = &dpt; /* * Now we create the threads that will actually * manage objects. */ for (i = 0; i < default_pager_internal_count; i++) { dpt_array[id] = start_default_pager_thread(id, TRUE); id++; } for (i = 0; i < default_pager_external_count; i++) { dpt_array[id] = start_default_pager_thread(id, FALSE); id++; } /* Is everybody ready? */ for (i = 0; i < id; i++) while (!dpt_array[i]) cthread_yield(); /* Tell the bootstrap process to go ahead. */ bootstrap_completed(bootstrap_port, mach_task_self()); /* Start servicing requests. */ server_options = MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SEQNO); for (;;) { mach_msg_server(default_pager_demux_default, default_pager_msg_size, default_pager_default_set, server_options); Panic("default server"); } }