Example #1
0
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);
}
Example #3
0
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;
}
Example #4
0
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;
}