/** Initialize Thread wrapper instance for main thread. * This will create an internal Thread instance such that it can be guaranteed that */ void Thread::init_main() { init_thread_key(); Thread *t = new Thread(MAIN_THREAD_NAME, pthread_self()); set_tsd_thread_instance(t); }
/** Initialize. * Kind of the base constructor. * @param name name of thread * @param op_mode operation mode */ void Thread::__constructor(const char *name, OpMode op_mode) { init_thread_key(); __prepfin_conc_loop = false; __coalesce_wakeups = false; __op_mode = op_mode; __name = strdup(name); __notification_listeners = new LockList<ThreadNotificationListener *>(); if ( __op_mode == OPMODE_WAITFORWAKEUP ) { __sleep_mutex = new Mutex(); __sleep_condition = new WaitCondition(__sleep_mutex); __waiting_for_wakeup = true; } else { __sleep_condition = NULL; __sleep_mutex = NULL; __waiting_for_wakeup = false; } __thread_id = 0; __flags = 0; __barrier = NULL; __started = false; __cancelled = false; __delete_on_exit = false; __prepfin_hold = false; __pending_wakeups = 0; loop_mutex = new Mutex(); finalize_prepared = false; __loop_done = true; __loop_done_mutex = new Mutex(); __loop_done_waitcond = new WaitCondition(__loop_done_mutex); loopinterrupt_antistarve_mutex = new Mutex(); __prepfin_hold_mutex = new Mutex(); __prepfin_hold_waitcond = new WaitCondition(__prepfin_hold_mutex); __startup_barrier = new Barrier(2); }
struct SVAThread * findNextFreeThread (void) { for (unsigned int index = 0; index < 4096; ++index) { if (__sync_bool_compare_and_swap (&(Threads[index].used), 0, 1)) { /* * Remember which thread is the one we've grabbed. */ struct SVAThread * newThread = Threads + index; /* * Do some basic initialization of the thread. */ newThread->integerState.valid = 0; newThread->savedICIndex = 0; newThread->ICFPIndex = 0; newThread->secmemSize = 0; newThread->numPushTargets = 0; newThread->secmemPML4e = 0; /* * This function currently sets the thread secret with a default * statically defined key. However, in the future will obtain said key * from the executable image. There is also some issue with * bootstrapping the initial key and whether or not on the first * execution of an application the key will need to be generated by SVA. * Thus, future design is yet to be done, however, the following function * should suffice to enable any of the above scenarios. * * TODO: The function currently uses a dummy static key, but in the * future will obtain the key from the executable image and then * decrypted with the VirtualGhost private key. */ if (vg) { init_thread_key(newThread); } #if DEBUG printf("<<<< SVA: Created new private key: value: %s\n", newThread->secret.key); #endif /* * Use the next-to-last interrupt context in the list as the first * interrupt context. This may be slightly wasteful, but it's a little * easier to make it work correctly right now. * * The processor's IST3 field should be configured so that the next * interrupt context is at maxIC - 2. */ sva_icontext_t * icontextp = newThread->interruptContexts + maxIC - 1; newThread->integerState.ist3 = ((uintptr_t) icontextp) - 0x10; newThread->integerState.kstackp = newThread->integerState.ist3; /* * Generate a random identifier for the new thread. */ if (vg) { newThread->rid = randomNumber(); } return newThread; } } panic ("SVA: findNextFreeThread: Exhausted SVA Threads!\n"); return 0; }