コード例 #1
0
void * MultiLockRandomSafeThread( void * p )
{
    const unsigned int value = reinterpret_cast< unsigned int >( p );
    unsigned int testCount = 0;
    unsigned int failCount = 0;
    volatile Thing * thing = nullptr;
    Thing::ThingPool pool;
    LevelMutexInfo::MutexContainer mutexes;
    mutexes.reserve( thingCount );

    unsigned int jj = 0;
    unsigned int place = 0;
    try
    {
        for ( unsigned int ii = 0; ii < thingCount; ++ii )
        {

            pool.clear();
            pool.reserve( thingCount );
            for ( place = 0; place < thingCount; ++place )
            {
                place += ::rand() % 3;
                if ( thingCount <= place )
                    break;
                thing = Thing::GetFromPool( place );
                assert( nullptr != thing );
                pool.push_back( thing );
            }
            const unsigned int poolCount = pool.size();

            mutexes.clear();
            for ( jj = 0; jj < poolCount; ++jj )
            {
                thing = pool[ jj ];
                assert( nullptr != thing );
                mutexes.push_back( &thing->GetMutex() );
            }

            MultiMutexLocker locker( mutexes );
            (void)locker;
            for ( jj = 0; jj < poolCount; ++jj )
            {
                thing = pool[ jj ];
                assert( nullptr != thing );
                thing->SetValue( value );
            }
            ::GoToSleep( 3 );

            for ( jj = 0; jj < poolCount; ++jj )
            {
                thing = pool[ jj ];
                assert( nullptr != thing );
                if ( thing->GetValue() != value )
                    failCount++;
                testCount++;
            }
        }
    }
    catch ( ... )
    {
        assert( false );
    }

    TestResults::GetIt()->SetResult( value, testCount, failCount );

    return nullptr;
}
コード例 #2
0
void SingleThreadComplexMultiLockTest( bool doSetup )
{

    ::srand( static_cast< unsigned int >( time( nullptr ) ) );
    if ( doSetup )
    {
        Thing::MakePool( thingCount );
    }

    const unsigned int priorLevel      = GetCurrentThreadsLevel();
    const unsigned int priorLockCount  = CountLocksInCurrentThread();
    const unsigned int priorMutexCount = CountMutexesInCurrentThread();
    const unsigned int priorLevelMutexCount = CountMutexesAtCurrentLevel();
    if ( LevelMutexInfo::UnlockedLevel == priorLevel )
    {
        assert( priorLockCount  == 0 );
        assert( priorMutexCount == 0 );
        assert( priorLevelMutexCount == 0 );
    }
    else
    {
        assert( priorLockCount  != 0 );
        assert( priorMutexCount != 0 );
        assert( priorLevelMutexCount != 0 );
        assert( priorLevelMutexCount <= priorMutexCount );
        assert( priorMutexCount <= priorLockCount );
    }

    volatile Thing * thing0 = Thing::GetFromPool( 0 );
    volatile Thing * thing1 = Thing::GetFromPool( 1 );
    volatile Thing * thing2 = Thing::GetFromPool( 2 );
    volatile Thing * thing3 = Thing::GetFromPool( 3 );
    volatile Thing * thing4 = Thing::GetFromPool( 4 );
    volatile Thing * thing5 = Thing::GetFromPool( 5 );
    volatile Thing * thing6 = Thing::GetFromPool( 6 );
    volatile Thing * thing7 = Thing::GetFromPool( 7 );
    assert( nullptr != thing0 );
    assert( nullptr != thing1 );
    assert( nullptr != thing2 );
    assert( nullptr != thing3 );
    assert( nullptr != thing4 );
    assert( nullptr != thing5 );
    assert( nullptr != thing6 );
    assert( nullptr != thing7 );

    LevelMutexInfo::MutexContainer mutexes;
    mutexes.reserve( thingCount );
    MutexErrors::Type result = LevelMutexInfo::MultiLock( mutexes );
    assert( result == MutexErrors::EmptyContainer );

    mutexes.push_back( &thing0->GetMutex() );
    mutexes.push_back( &thing1->GetMutex() );
    mutexes.push_back( &thing2->GetMutex() );
    mutexes.push_back( &thing3->GetMutex() );
    mutexes.push_back( &thing4->GetMutex() );
    mutexes.push_back( &thing5->GetMutex() );
    mutexes.push_back( &thing6->GetMutex() );
    mutexes.push_back( &thing7->GetMutex() );

    result = LevelMutexInfo::MultiLock( mutexes );
    assert( result == MutexErrors::Success );
    assert( GetCurrentThreadsLevel()      == thing0->GetMutex().GetLevel() );
    assert( CountLocksInCurrentThread()   == priorLockCount  + thingCount );
    result = LevelMutexInfo::MultiUnlock( mutexes );
    assert( result == MutexErrors::Success );
    assert( GetCurrentThreadsLevel()      == priorLevel );
    assert( CountLocksInCurrentThread()   == priorLockCount );
    assert( CountMutexesInCurrentThread() == priorMutexCount );
    assert( CountMutexesAtCurrentLevel()  == priorLevelMutexCount );

    mutexes.clear();
    mutexes.push_back( &thing7->GetMutex() );
    mutexes.push_back( &thing6->GetMutex() );
    mutexes.push_back( &thing5->GetMutex() );
    mutexes.push_back( &thing4->GetMutex() );
    mutexes.push_back( &thing3->GetMutex() );
    mutexes.push_back( &thing2->GetMutex() );
    mutexes.push_back( &thing1->GetMutex() );
    mutexes.push_back( &thing0->GetMutex() );
    result = LevelMutexInfo::MultiLock( mutexes );
    assert( result == MutexErrors::Success );
    assert( GetCurrentThreadsLevel()      == thing0->GetMutex().GetLevel() );
    assert( CountLocksInCurrentThread()   == priorLockCount  + thingCount );
    result = LevelMutexInfo::MultiUnlock( mutexes );
    assert( result == MutexErrors::Success );
    assert( GetCurrentThreadsLevel()      == priorLevel );
    assert( CountLocksInCurrentThread()   == priorLockCount );
    assert( CountMutexesInCurrentThread() == priorMutexCount );
    assert( CountMutexesAtCurrentLevel()  == priorLevelMutexCount );

    RandomizeMutexOrder( mutexes );
    result = LevelMutexInfo::MultiLock( mutexes );
    assert( result == MutexErrors::Success );
    assert( GetCurrentThreadsLevel()      == thing0->GetMutex().GetLevel() );
    assert( CountLocksInCurrentThread()   == priorLockCount  + thingCount );
    result = LevelMutexInfo::MultiUnlock( mutexes );
    assert( result == MutexErrors::Success );
    assert( GetCurrentThreadsLevel()      == priorLevel );
    assert( CountLocksInCurrentThread()   == priorLockCount );
    assert( CountMutexesInCurrentThread() == priorMutexCount );
    assert( CountMutexesAtCurrentLevel()  == priorLevelMutexCount );

    if ( doSetup )
        Thing::DestroyPool();
}