VOID ThreadStart(THREADID threadIndex, CONTEXT *ctxt, INT32 flags, VOID *v) { PRINT_ME_AND_MY_FATHER(); // only the new thread should check it if (PIN_GetParentTid() != INVALID_OS_THREAD_ID) { TEST(PIN_GetParentTid() == father_id, "PIN_GetParentTid failed"); } TEST(PIN_ThreadUid() != INVALID_PIN_THREAD_UID, "PIN_ThreadUid failed"); }
Thread * Thread::current (void) { // Get the current thread in TLS, and return if exists. THREADID thr_id = PIN_ThreadId (); Thread * thr = Thread::current_.get (thr_id); if (0 != thr) return thr; // This could be the main thread, which does not have an Thread object // in the TLS. So, create a new thread, and store it. thr = new Thread (thr_id, PIN_GetTid (), PIN_ThreadUid (), PIN_GetParentTid ()); Thread::current_.set (thr_id, thr); return thr; }
VOID Thread::__thr_run (VOID * arg) { // Get the thread object, and update its remaining attributes. Thread * thr = reinterpret_cast <Thread *> (arg); // Set the current thread to the Thread object. This allows the // client to access the Thread object via the current () method. Thread::current_.set (thr->thr_id_, thr); do { Write_Guard <RW_Mutex> guard (thr->rw_mutex_); thr->os_thr_id_ = PIN_GetTid (); thr->parent_os_thr_id_ = PIN_GetParentTid (); // Set the state to running. thr->state_ = RUNNING; } while (0); // Determine what run method we should invoke. Either we invoke the run() // method on the runnable_ object contained in the thread, or we invoke // the run() method on the thread. The runnable_ variable takes precedence // over the run() method on the Thread. Runnable * runnable = thr->runnable_; if (0 == runnable) runnable = thr; runnable->run (); do { // Reset the thread state. Write_Guard <RW_Mutex> guard (thr->rw_mutex_); thr->state_ = TERMINATED; } while (0); }