void test_mutex_timed_lock(P &sm) { { shared_val = 0; data<P> m1(1, sm, 3); data<P> m2(2, sm, 3); // Locker one launches, holds the lock for 3*BaseSeconds seconds. boost::thread tm1(thread_adapter<P>(&timed_wait_and_sleep, &m1, sm)); //Wait 1*BaseSeconds boost::thread::sleep(xsecs(1*BaseSeconds)); // Locker two launches, holds the lock for 3*BaseSeconds seconds. boost::thread tm2(thread_adapter<P>(&timed_wait_and_sleep, &m2, sm)); //Wait completion tm1.join(); tm2.join(); //Both should succeed locking assert(m1.m_value == 1); assert(m2.m_value == 2); } { shared_val = 0; data<P> m1(1, sm, 3); data<P> m2(2, sm, 3); // Locker one launches, holds the lock for 3*BaseSeconds seconds. boost::thread tm1(thread_adapter<P>(&timed_wait_and_sleep, &m1, sm)); //Wait 1*BaseSeconds boost::thread::sleep(xsecs(1*BaseSeconds)); // Locker two launches, holds the lock for 3*BaseSeconds seconds. boost::thread tm2(thread_adapter<P>(&timed_wait_and_sleep, &m2, sm)); //Wait completion tm1.join(); tm2.join(); //Both should succeed locking assert(m1.m_value == 1); assert(m2.m_value == 2); } }
void test_try_sharable_mutex() { SM mtx; data<SM> s1(1); data<SM> e1(2); data<SM> e2(3); // We start with some specialized tests for "try" behavior shared_val = 0; // Writer one launches, holds the lock for 3*BaseSeconds seconds. boost::thread tw1(thread_adapter<SM>(try_exclusive,&e1,mtx)); // Reader one launches, "clearly" after writer #1 holds the lock // and before it releases the lock. boost::thread::sleep(xsecs(1*BaseSeconds)); boost::thread thr1(thread_adapter<SM>(try_shared,&s1,mtx)); // Writer two launches in the same timeframe. boost::thread tw2(thread_adapter<SM>(try_exclusive,&e2,mtx)); tw2.join(); thr1.join(); tw1.join(); BOOST_INTERPROCES_CHECK(e1.m_value == 10); BOOST_INTERPROCES_CHECK(s1.m_value == -1); // Try would return w/o waiting BOOST_INTERPROCES_CHECK(e2.m_value == -1); // Try would return w/o waiting }
void wait_and_sleep(void *arg, P &sm) { data<P> *pdata = static_cast<data<P>*>(arg); boost::interprocess::scoped_lock<P> l(sm); boost::thread::sleep(xsecs(3*BaseSeconds)); ++shared_val; pdata->m_value = shared_val; }
void plain_exclusive(void *arg, SM &sm) { data<SM> *pdata = static_cast<data<SM>*>(arg); boost::interprocess::scoped_lock<SM> l(sm); boost::thread::sleep(xsecs(3*BaseSeconds)); shared_val += 10; pdata->m_value = shared_val; }
void plain_shared(void *arg, SM &sm) { data<SM> *pdata = static_cast<data<SM>*>(arg); boost::interprocess::sharable_lock<SM> l(sm); if(pdata->m_secs){ boost::thread::sleep(xsecs(pdata->m_secs*BaseSeconds)); } pdata->m_value = shared_val; }
void try_exclusive(void *arg, SM &sm) { data<SM> *pdata = static_cast<data<SM>*>(arg); boost::interprocess::scoped_lock<SM> l(sm, boost::interprocess::defer_lock); if (l.try_lock()){ boost::thread::sleep(xsecs(3*BaseSeconds)); shared_val += 10; pdata->m_value = shared_val; } }
void timed_wait_and_sleep(void *arg, P &sm) { data<P> *pdata = static_cast<data<P>*>(arg); boost::posix_time::ptime pt(delay(pdata->m_secs)); boost::interprocess::scoped_lock<P> l (sm, boost::interprocess::defer_lock); if (l.timed_lock(pt)){ boost::thread::sleep(xsecs(3*BaseSeconds)); ++shared_val; pdata->m_value = shared_val; } }
void timed_shared(void *arg, SM &sm) { data<SM> *pdata = static_cast<data<SM>*>(arg); boost::posix_time::ptime pt(delay(pdata->m_secs)); boost::interprocess::sharable_lock<SM> l(sm, boost::interprocess::defer_lock); if (l.timed_lock(pt)){ if(pdata->m_secs){ boost::thread::sleep(xsecs(pdata->m_secs*BaseSeconds)); } pdata->m_value = shared_val; } }
void test_timed_sharable_mutex() { SM m1, m2, m3, m4; SM *pm1, *pm2, *pm3, *pm4; if(SameObject){ pm1 = pm2 = pm3 = pm4 = &m1; } else{ pm1 = &m1; pm2 = &m2; pm3 = &m3; pm4 = &m4; } data<SM> s1(1,1*BaseSeconds); data<SM> s2(2,3*BaseSeconds); data<SM> e1(3,3*BaseSeconds); data<SM> e2(4,1*BaseSeconds); // We begin with some specialized tests for "timed" behavior shared_val = 0; // Writer one will hold the lock for 3*BaseSeconds seconds. boost::thread tw1(thread_adapter<SM>(timed_exclusive,&e1,*pm1)); boost::thread::sleep(xsecs(1*BaseSeconds)); // Writer two will "clearly" try for the lock after the readers // have tried for it. Writer will wait up 1*BaseSeconds seconds for the lock. // This write will fail. boost::thread tw2(thread_adapter<SM>(timed_exclusive,&e2,*pm2)); // Readers one and two will "clearly" try for the lock after writer // one already holds it. 1st reader will wait 1*BaseSeconds seconds, and will fail // to get the lock. 2nd reader will wait 3*BaseSeconds seconds, and will get // the lock. boost::thread thr1(thread_adapter<SM>(timed_shared,&s1,*pm3)); boost::thread thr2(thread_adapter<SM>(timed_shared,&s2,*pm4)); tw1.join(); thr1.join(); thr2.join(); tw2.join(); assert(e1.m_value == 10); assert(s1.m_value == -1); assert(s2.m_value == 10); assert(e2.m_value == -1); }
void test_try_sharable_mutex() { SM m1, m2, m3; SM *pm1, *pm2, *pm3; if(SameObject){ pm1 = pm2 = pm3 = &m1; } else{ pm1 = &m1; pm2 = &m2; pm3 = &m3; } data<SM> s1(1); data<SM> e1(2); data<SM> e2(3); // We start with some specialized tests for "try" behavior shared_val = 0; // Writer one launches, holds the lock for 3*BaseSeconds seconds. boost::thread tw1(thread_adapter<SM>(try_exclusive,&e1,*pm1)); // Reader one launches, "clearly" after writer #1 holds the lock // and before it releases the lock. boost::thread::sleep(xsecs(1*BaseSeconds)); boost::thread thr1(thread_adapter<SM>(try_shared,&s1,*pm2)); // Writer two launches in the same timeframe. boost::thread tw2(thread_adapter<SM>(try_exclusive,&e2,*pm3)); tw2.join(); thr1.join(); tw1.join(); assert(e1.m_value == 10); assert(s1.m_value == -1); // Try would return w/o waiting assert(e2.m_value == -1); // Try would return w/o waiting }
void test_timed_sharable_mutex() { SM mtx; data<SM> s1(1,1*BaseSeconds); data<SM> s2(2,3*BaseSeconds); data<SM> e1(3,3*BaseSeconds); data<SM> e2(4,1*BaseSeconds); // We begin with some specialized tests for "timed" behavior shared_val = 0; // Writer one will hold the lock for 3*BaseSeconds seconds. boost::thread tw1(thread_adapter<SM>(timed_exclusive,&e1,mtx)); boost::thread::sleep(xsecs(1*BaseSeconds)); // Writer two will "clearly" try for the lock after the readers // have tried for it. Writer will wait up 1*BaseSeconds seconds for the lock. // This write will fail. boost::thread tw2(thread_adapter<SM>(timed_exclusive,&e2,mtx)); // Readers one and two will "clearly" try for the lock after writer // one already holds it. 1st reader will wait 1*BaseSeconds seconds, and will fail // to get the lock. 2nd reader will wait 3*BaseSeconds seconds, and will get // the lock. boost::thread thr1(thread_adapter<SM>(timed_shared,&s1,mtx)); boost::thread thr2(thread_adapter<SM>(timed_shared,&s2,mtx)); tw1.join(); thr1.join(); thr2.join(); tw2.join(); BOOST_INTERPROCES_CHECK(e1.m_value == 10); BOOST_INTERPROCES_CHECK(s1.m_value == -1); BOOST_INTERPROCES_CHECK(s2.m_value == 10); BOOST_INTERPROCES_CHECK(e2.m_value == -1); }
void test_plain_sharable_mutex() { { shared_val = 0; SM mtx; data<SM> s1(1); data<SM> s2(2); data<SM> e1(1); data<SM> e2(2); // Writer one launches, holds the lock for 3*BaseSeconds seconds. boost::thread tw1(thread_adapter<SM>(plain_exclusive, &e1, mtx)); // Writer two launches, tries to grab the lock, "clearly" // after Writer one will already be holding it. boost::thread::sleep(xsecs(1*BaseSeconds)); boost::thread tw2(thread_adapter<SM>(plain_exclusive, &e2, mtx)); // Reader one launches, "clearly" after writer two, and "clearly" // while writer 1 still holds the lock boost::thread::sleep(xsecs(1*BaseSeconds)); boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, mtx)); boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, mtx)); thr2.join(); thr1.join(); tw2.join(); tw1.join(); //We can only assure that the writer will be first BOOST_INTERPROCES_CHECK(e1.m_value == 10); //A that we will execute all BOOST_INTERPROCES_CHECK(s1.m_value == 20 || s2.m_value == 20 || e2.m_value == 20); } { shared_val = 0; SM mtx; data<SM> s1(1, 3); data<SM> s2(2, 3); data<SM> e1(1); data<SM> e2(2); //We launch 2 readers, that will block for 3*BaseTime seconds boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, mtx)); boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, mtx)); //Make sure they try to hold the sharable lock boost::thread::sleep(xsecs(1*BaseSeconds)); // We launch two writers, that should block until the readers end boost::thread tw1(thread_adapter<SM>(plain_exclusive,&e1, mtx)); boost::thread tw2(thread_adapter<SM>(plain_exclusive,&e2, mtx)); thr2.join(); thr1.join(); tw2.join(); tw1.join(); //We can only assure that the shared will finish first... BOOST_INTERPROCES_CHECK(s1.m_value == 0 || s2.m_value == 0); //...and writers will be mutually excluded after readers BOOST_INTERPROCES_CHECK((e1.m_value == 10 && e2.m_value == 20) || (e1.m_value == 20 && e2.m_value == 10) ); } }
void test_plain_sharable_mutex() { { shared_val = 0; SM m1, m2, m3, m4; SM *pm1, *pm2, *pm3, *pm4; if(SameObject){ pm1 = pm2 = pm3 = pm4 = &m1; } else{ pm1 = &m1; pm2 = &m2; pm3 = &m3; pm4 = &m4; } data<SM> s1(1); data<SM> s2(2); data<SM> e1(1); data<SM> e2(2); // Writer one launches, holds the lock for 3*BaseSeconds seconds. boost::thread tw1(thread_adapter<SM>(plain_exclusive, &e1, *pm1)); // Writer two launches, tries to grab the lock, "clearly" // after Writer one will already be holding it. boost::thread::sleep(xsecs(1*BaseSeconds)); boost::thread tw2(thread_adapter<SM>(plain_exclusive, &e2, *pm2)); // Reader one launches, "clearly" after writer two, and "clearly" // while writer 1 still holds the lock boost::thread::sleep(xsecs(1*BaseSeconds)); boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, *pm3)); boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, *pm4)); thr2.join(); thr1.join(); tw2.join(); tw1.join(); //We can only assure that the writer will be first assert(e1.m_value == 10); //A that we will execute all assert(s1.m_value == 20 || s2.m_value == 20 || e2.m_value == 20); } { shared_val = 0; SM m1, m2, m3, m4; SM *pm1, *pm2, *pm3, *pm4; if(SameObject){ pm1 = pm2 = pm3 = pm4 = &m1; } else{ pm1 = &m1; pm2 = &m2; pm3 = &m3; pm4 = &m4; } data<SM> s1(1, 3); data<SM> s2(2, 3); data<SM> e1(1); data<SM> e2(2); //We launch 2 readers, that will block for 3*BaseTime seconds boost::thread thr1(thread_adapter<SM>(plain_shared,&s1,*pm1)); boost::thread thr2(thread_adapter<SM>(plain_shared,&s2,*pm2)); //Make sure they try to hold the sharable lock boost::thread::sleep(xsecs(1*BaseSeconds)); // We launch two writers, that should block until the readers end boost::thread tw1(thread_adapter<SM>(plain_exclusive,&e1,*pm3)); boost::thread tw2(thread_adapter<SM>(plain_exclusive,&e2,*pm4)); thr2.join(); thr1.join(); tw2.join(); tw1.join(); //We can only assure that the shared will finish first... assert(s1.m_value == 0 || s2.m_value == 0); //...and writers will be mutually excluded after readers assert((e1.m_value == 10 && e2.m_value == 20) || (e1.m_value == 20 && e2.m_value == 10) ); } }