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); }
static void DoTestTryLocks(UINT32 *done) { // This is a collection of single-thread tests that make sure that the // various "try" operations succeed or fail as expected. BOOL gotLock = PIN_MutexTryLock(&Mutex); if (!gotLock) { std::cout << "Failure on uncontended PIN_MutexTryLock" << std::endl; PIN_ExitProcess(1); } gotLock = PIN_MutexTryLock(&Mutex); if (gotLock) { std::cout << "PIN_MutexTryLock was able to get a lock twice" << std::endl; PIN_ExitProcess(1); } gotLock = PIN_RWMutexTryWriteLock(&RWMutex); if (!gotLock) { std::cout << "Failure on uncontended PIN_RWMutexTryWriteLock" << std::endl; PIN_ExitProcess(1); } gotLock = PIN_RWMutexTryWriteLock(&RWMutex); if (gotLock) { std::cout << "PIN_RWMutexTryWriteLock was able to get a lock twice" << std::endl; PIN_ExitProcess(1); } gotLock = PIN_RWMutexTryReadLock(&RWMutex); if (gotLock) { std::cout << "PIN_RWMutexTryReadLock was able to get a lock when writer owns it" << std::endl; PIN_ExitProcess(1); } PIN_RWMutexUnlock(&RWMutex); gotLock = PIN_RWMutexTryReadLock(&RWMutex); if (!gotLock) { std::cout << "Failure on uncontended PIN_RWMutexTryReadLock" << std::endl; PIN_ExitProcess(1); } gotLock = PIN_RWMutexTryReadLock(&RWMutex); if (!gotLock) { std::cout << "Unable to get a reader lock twice" << std::endl; PIN_ExitProcess(1); } PIN_SemaphoreSet(&Sem1); if (!PIN_SemaphoreIsSet(&Sem1)) { std::cout << "Expected 'set' status from PIN_SemaphoreIsSet" << std::endl; PIN_ExitProcess(1); } PIN_SemaphoreClear(&Sem1); if (PIN_SemaphoreIsSet(&Sem1)) { std::cout << "Expected 'clear' status from PIN_SemaphoreIsSet" << std::endl; PIN_ExitProcess(1); } if (PIN_SemaphoreTimedWait(&Sem1, 1)) { std::cout << "Expected PIN_SemaphoreTimedWait to time-out" << std::endl; PIN_ExitProcess(1); } *done = 1; }
int main(int argc, char * argv[]) { PIN_Init(argc, argv); PIN_InitSymbols(); RegThreadInfo = PIN_ClaimToolRegister(); if (RegThreadInfo == REG_INVALID()) { std::cout << "Out of tool registers" << std::endl; PIN_ExitProcess(1); } // Get the test type and initialize the corresponding lock variable. // TestType = GetTestType(KnobTest.Value()); switch (TestType) { case TEST_NONE: std::cout << "Must specify a test to run with the '-test' knob" << std::endl; PIN_ExitProcess(1); break; case TEST_INVALID: std::cout << "Invalid test name: " << KnobTest.Value() << std::endl; PIN_ExitProcess(1); break; case TEST_LOCK_INTEGRITY: case TEST_LOCK_STRESS: PIN_InitLock(&Lock); break; case TEST_MUTEX_INTEGRITY: case TEST_MUTEX_STRESS: case TEST_MUTEX_TRYSTRESS: PIN_MutexInit(&Mutex); break; case TEST_WRITER_INTEGRITY: case TEST_WRITER_STRESS: case TEST_WRITER_TRYSTRESS: case TEST_READER_STRESS: case TEST_READER_TRYSTRESS: case TEST_RW_INTEGRITY: case TEST_RW_STRESS: case TEST_RW_TRYSTRESS: PIN_RWMutexInit(&RWMutex); break; case TEST_SEMAPHORE: PIN_SemaphoreInit(&Sem1); PIN_SemaphoreInit(&Sem2); PIN_SemaphoreSet(&Sem1); PIN_MutexInit(&Mutex); break; case TEST_TRYLOCKS: PIN_MutexInit(&Mutex); PIN_RWMutexInit(&RWMutex); PIN_SemaphoreInit(&Sem1); break; default: ASSERTX(0); } PIN_AddThreadStartFunction(OnThreadStart, 0); PIN_AddThreadFiniFunction(OnThreadFini, 0); RTN_AddInstrumentFunction(InstrumentRtn, 0); PIN_AddFiniFunction(OnExit, 0); PIN_StartProgram(); return 0; }