static void DoTestSemaphore(THREAD_INFO *info, UINT32 *done) { // This test assumes exactly two threads. The two threads take turns pinging // each other's semaphore. We make sure that a thread does not wake up from // the semaphore unless it is set. We also check for deadlocks due to missing // wakeups. if (info->_workerId == 0) { PIN_SemaphoreWait(&Sem1); if (!PIN_SemaphoreIsSet(&Sem1)) { std::cout << "SemaphoreWait returned, but semaphore is not set" << std::endl; PIN_ExitProcess(1); } PIN_MutexLock(&Mutex); PIN_SemaphoreClear(&Sem1); PIN_SemaphoreSet(&Sem2); PIN_MutexUnlock(&Mutex); } else { PIN_SemaphoreWait(&Sem2); if (!PIN_SemaphoreIsSet(&Sem2)) { std::cout << "SemaphoreWait returned, but semaphore is not set" << std::endl; PIN_ExitProcess(1); } PIN_MutexLock(&Mutex); PIN_SemaphoreClear(&Sem2); PIN_SemaphoreSet(&Sem1); PIN_MutexUnlock(&Mutex); } if (CheckIfDone(info, done)) { PIN_SemaphoreSet(&Sem1); PIN_SemaphoreSet(&Sem2); } }
/* ===================================================================== * Called on DoBreakpoint() for each thread. * Waits for all the threads to reach this point, filling the vector of * the created thread IDs, and then release all the threads. * ===================================================================== */ static void WaitForAllThreadsToStart(THREADID tid) { PIN_MutexLock(&MtxVecThreadIds); VecThreadIds.push_back(tid); if (VecThreadIds.size() >= KnobThreads.Value()) { PrintAllThreadIDs(); AllThreadsWereStarted = true; PIN_SemaphoreSet(&SemAllThreadStarted); } PIN_MutexUnlock(&MtxVecThreadIds); PIN_SemaphoreWait(&SemAllThreadStarted); }