bool RandomizeMutexOrder( LevelMutexInfo::MutexContainer & mutexes )
{
    unsigned int count = mutexes.size();
    if ( count < 2 )
        return false;

    LevelMutexInfo::MutexContainer randomMutexes;
    for ( unsigned int ii = 0; ii < count; ++ii )
    {
        volatile LevelMutexInfo * mutex = nullptr;
        const unsigned int sizeNow = mutexes.size();
        if ( 1 < sizeNow )
        {
            unsigned int index = ( ::rand() % sizeNow );
            mutex = mutexes[ index ];
            if ( index < sizeNow - 1 )
                mutexes[ index ] = mutexes[ sizeNow - 1 ];
        }
        else
        {
            mutex = mutexes[ 0 ];
        }
        mutexes.pop_back();
        randomMutexes.push_back( mutex );
    }

    mutexes = randomMutexes;
    return true;
}
Example #2
0
void UnlockThese( SomeThingPool & pool )
{

    const unsigned int count = pool.size();
    assert( 0 != count );
    SortByLevel( pool );

    volatile SomeThing * thing = pool[ 0 ];
    assert( NULL != thing );
    unsigned int level = thing->GetLevel();
    LevelMutexInfo::MutexContainer mutexes;
    MutexErrors::Type result = MutexErrors::Success;
    unsigned int ii = 0;

    for ( ii = 0; ii < count; ++ii )
    {
        thing = pool[ ii ];
        assert( NULL != thing );
        if ( level != thing->GetLevel() )
        {
            assert( mutexes.size() != 0 );
            result = LevelMutexInfo::MultiUnlock( mutexes );
            assert( result == MutexErrors::Success );
            mutexes.clear();
            level = thing->GetLevel();
        }
        mutexes.push_back( &thing->GetMutex() );
    }

    assert( mutexes.size() != 0 );
    result = LevelMutexInfo::MultiUnlock( mutexes );
    assert( result == MutexErrors::Success );

    for ( ii = 0; ii < count; ++ii )
    {
        thing = pool[ ii ];
        assert( NULL != thing );
        assert( !thing->GetMutex().IsLockedByCurrentThread() );
    }
}