void Client::run() { busy_rw.read_lock(); if (hairdresser_->busy){ busy_rw.read_unlock(); // client wait until Hairdresser make haircut for another client cerr_rw.write_lock(); cerr<<"Client "<<number<<" : wait"<<endl; cerr_rw.write_unlock(); condition.wait(); // client enter to Hairdresser room busy_rw.write_lock(); hairdresser_->busy = true; cerr_rw.write_lock(); cerr<<"Client "<< number <<" : enter to Hairdresser room"<<endl; cerr_rw.write_unlock(); client_rw.write_lock(); hairdresser_->client = this; client_rw.write_unlock(); busy_rw.write_unlock(); }else{ busy_rw.read_unlock(); // client enter to Hairdresser room busy_rw.write_lock(); hairdresser_->busy = true; busy_rw.write_unlock(); client_rw.write_lock(); hairdresser_->client = this; client_rw.write_unlock(); cerr_rw.write_lock(); cerr<<"Client "<<number<<" wake up Hairdresser"<<endl; cerr_rw.write_unlock(); condition2.notify(); } }
int main(int argc, char **argv) { uint32_t which_lock; // 1-5 uint32_t which_side; // 0 or 1 uint32_t lock_unlock; // 0 or 1 RWLock *rwlock; name = argv[0]; if (argc != 4) usage(); if (strlen(argv[1]) != 1 || strlen(argv[2]) != 1 || strlen(argv[3]) != 1) usage(); which_lock = atoi(argv[1]); if (which_lock < 1 || which_lock > 5) usage(); if (argv[2][0] == 'r') which_side = 0; else if (argv[2][0] == 'w') which_side = 1; else usage(); if (argv[3][0] == 'l') lock_unlock = 0; else if (argv[3][0] == 'u') lock_unlock = 1; else usage(); rwlock = new RWLock(0x10000 * which_lock); if (which_side == 0) if (lock_unlock == 0) rwlock->read_lock(); else rwlock->read_unlock(); else if (lock_unlock == 0) rwlock->write_lock(); else rwlock->write_unlock(); return 0; }
inline ~ReadGuard() { if (ref != nullptr) ref->read_unlock(); }
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); }