static void* RWRunner(void* arg) { struct timeval tv; int op, op2, interval; RWLock* rwlock; gettimeofday(&tv, NULL); rwlock = new RWLock(reinterpret_cast<int64_t>(arg)); while (!threadStop) { op = rand_r(reinterpret_cast<uint32_t*>(&tv.tv_usec)) % 10; if (op < 8) // read { interval = rand_r(reinterpret_cast<uint32_t*>(&tv.tv_usec)) % 100000; rwlock->read_lock(); rwlock->lock(); CPPUNIT_ASSERT(rwlock->getReading() > 0); CPPUNIT_ASSERT(rwlock->getWriting() == 0); rwlock->unlock(); usleep(interval); op2 = rand_r(reinterpret_cast<uint32_t*>(&tv.tv_usec)) % 2; if (op2) { rwlock->upgrade_to_write(); rwlock->lock(); CPPUNIT_ASSERT(rwlock->getReading() == 0); CPPUNIT_ASSERT(rwlock->getWriting() == 1); rwlock->unlock(); usleep(interval); rwlock->write_unlock(); } else { /* For testing the lock recovery code in the BRM workernodes */ /* int crash = rand_r((uint32_t *) &tv.tv_usec) % 100; if (crash > 0) // 1% chance of crashing rwlock->read_unlock(); */ } } else if (op < 9) // write { interval = rand_r(reinterpret_cast<uint32_t*>(&tv.tv_usec)) % 100000; rwlock->write_lock(); rwlock->lock(); CPPUNIT_ASSERT(rwlock->getReading() == 0); CPPUNIT_ASSERT(rwlock->getWriting() == 1); rwlock->unlock(); usleep(interval); op2 = rand_r(reinterpret_cast<uint32_t*>(&tv.tv_usec)) % 2; if (op2) { rwlock->downgrade_to_read(); rwlock->lock(); CPPUNIT_ASSERT(rwlock->getReading() > 0); CPPUNIT_ASSERT(rwlock->getWriting() == 0); rwlock->unlock(); usleep(interval); rwlock->read_unlock(); } else rwlock->write_unlock(); } else if (op == 9) // delete { delete rwlock; rwlock = new RWLock(reinterpret_cast<int64_t>(arg)); } } delete rwlock; pthread_exit(0); }