Changeset View
Changeset View
Standalone View
Standalone View
src/test/rcu_tests.cpp
Show First 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | for (int i = 0; i < COUNT; i++) { | ||||
std::thread tsync( | std::thread tsync( | ||||
[&] { synchronize(childstep, parentstep, cs, cond, syncRev); }); | [&] { synchronize(childstep, parentstep, cs, cond, syncRev); }); | ||||
tlock.join(); | tlock.join(); | ||||
tsync.join(); | tsync.join(); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Version of Boost::test prior to 1.64 have issues when dealing with nullptr_t. | |||||
* In order to work around this, we ensure that the null pointers are typed in a | |||||
* way that Boost will like better. | |||||
* | |||||
* TODO: Use nullptr directly once the minimum version of boost is 1.64 or more. | |||||
*/ | |||||
#define NULLPTR(T) static_cast<T *>(nullptr) | |||||
BOOST_AUTO_TEST_CASE(cleanup_test) { | BOOST_AUTO_TEST_CASE(cleanup_test) { | ||||
BOOST_CHECK(RCUTest::getCleanups().empty()); | BOOST_CHECK(RCUTest::getCleanups().empty()); | ||||
bool isClean1 = false; | bool isClean1 = false; | ||||
RCULock::registerCleanup([&] { isClean1 = true; }); | RCULock::registerCleanup([&] { isClean1 = true; }); | ||||
BOOST_CHECK(!isClean1); | BOOST_CHECK(!isClean1); | ||||
BOOST_CHECK_EQUAL(RCUTest::getCleanups().size(), 1); | BOOST_CHECK_EQUAL(RCUTest::getCleanups().size(), 1); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | explicit RCURefTestItem(const std::function<void()> &fun) | ||||
: cleanupfun(fun) {} | : cleanupfun(fun) {} | ||||
~RCURefTestItem() { cleanupfun(); } | ~RCURefTestItem() { cleanupfun(); } | ||||
uint32_t getRefCount() const { return refcount.load(); } | uint32_t getRefCount() const { return refcount.load(); } | ||||
}; | }; | ||||
BOOST_AUTO_TEST_CASE(rcuref_test) { | BOOST_AUTO_TEST_CASE(rcuref_test) { | ||||
// Make sure it works for null. | // Make sure it works for null. | ||||
{ RCUPtr<RCURefTestItem> rcuptr(nullptr); } | { | ||||
RCURefTestItem *ptr = nullptr; | |||||
RCUPtr<RCURefTestItem>::copy(ptr); | |||||
RCUPtr<RCURefTestItem>::acquire(ptr); | |||||
} | |||||
// Check the destruction mechanism. | // Check the destruction mechanism. | ||||
bool isDestroyed = false; | bool isDestroyed = false; | ||||
{ | { | ||||
auto rcuptr = RCUPtr<RCURefTestItem>::make([&] { isDestroyed = true; }); | auto rcuptr = RCUPtr<RCURefTestItem>::make([&] { isDestroyed = true; }); | ||||
BOOST_CHECK_EQUAL(rcuptr->getRefCount(), 0); | BOOST_CHECK_EQUAL(rcuptr->getRefCount(), 0); | ||||
} | } | ||||
Show All 24 Lines | BOOST_AUTO_TEST_CASE(rcuref_test) { | ||||
BOOST_CHECK_EQUAL(gptr->getRefCount(), 0); | BOOST_CHECK_EQUAL(gptr->getRefCount(), 0); | ||||
RCULock::synchronize(); | RCULock::synchronize(); | ||||
BOOST_CHECK(!isDestroyed); | BOOST_CHECK(!isDestroyed); | ||||
gptr = RCUPtr<RCURefTestItem>(); | gptr = RCUPtr<RCURefTestItem>(); | ||||
BOOST_CHECK(!isDestroyed); | BOOST_CHECK(!isDestroyed); | ||||
RCULock::synchronize(); | RCULock::synchronize(); | ||||
BOOST_CHECK(isDestroyed); | BOOST_CHECK(isDestroyed); | ||||
// Check various operators. | |||||
BOOST_CHECK_EQUAL(gptr.get(), NULLPTR(RCURefTestItem)); | |||||
BOOST_CHECK_EQUAL(gptr.get(), &*gptr); | |||||
BOOST_CHECK(!gptr); | |||||
auto ptr = new RCURefTestItem([] {}); | |||||
auto oldPtr = ptr; | |||||
gptr = RCUPtr<RCURefTestItem>::acquire(ptr); | |||||
BOOST_CHECK_EQUAL(gptr.get(), oldPtr); | |||||
BOOST_CHECK_EQUAL(&*gptr, oldPtr); | |||||
BOOST_CHECK(gptr); | |||||
} | } | ||||
class RCURefMoveTestItem { | class RCURefMoveTestItem { | ||||
const std::function<void()> cleanupfun; | const std::function<void()> cleanupfun; | ||||
public: | public: | ||||
explicit RCURefMoveTestItem(const std::function<void()> &fun) | explicit RCURefMoveTestItem(const std::function<void()> &fun) | ||||
: cleanupfun(fun) {} | : cleanupfun(fun) {} | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | // Check we can return from a function. | ||||
RCULock::synchronize(); | RCULock::synchronize(); | ||||
BOOST_CHECK(!isDestroyed); | BOOST_CHECK(!isDestroyed); | ||||
} | } | ||||
BOOST_CHECK(!isDestroyed); | BOOST_CHECK(!isDestroyed); | ||||
RCULock::synchronize(); | RCULock::synchronize(); | ||||
BOOST_CHECK(isDestroyed); | BOOST_CHECK(isDestroyed); | ||||
// Acquire/release workflow. | |||||
isDestroyed = false; | |||||
auto ptr = new RCURefMoveTestItem([&] { isDestroyed = true; }); | |||||
auto ptrCopy = ptr; | |||||
BOOST_CHECK_THROW(RCUPtr<RCURefMoveTestItem>::copy(ptr), | |||||
std::runtime_error); | |||||
rcuptr1 = RCUPtr<RCURefMoveTestItem>::acquire(ptr); | |||||
BOOST_CHECK_EQUAL(rcuptr1.get(), ptrCopy); | |||||
BOOST_CHECK_EQUAL(ptr, NULLPTR(RCURefMoveTestItem)); | |||||
ptr = rcuptr1.release(); | |||||
BOOST_CHECK_EQUAL(rcuptr1.get(), NULLPTR(RCURefMoveTestItem)); | |||||
BOOST_CHECK_EQUAL(ptr, ptrCopy); | |||||
RCULock::synchronize(); | |||||
BOOST_CHECK(!isDestroyed); | |||||
RCUPtr<RCURefMoveTestItem>::acquire(ptr); | |||||
BOOST_CHECK(!isDestroyed); | |||||
RCULock::synchronize(); | |||||
BOOST_CHECK(isDestroyed); | |||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |