13
0

Add RCU unit test

This commit is contained in:
Robin Gareus 2020-11-05 02:24:54 +01:00
parent 1a73ef16f4
commit 88fc0ed392
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 144 additions and 0 deletions

108
libs/pbd/test/rcu_test.cc Normal file
View File

@ -0,0 +1,108 @@
#include <glibmm.h>
#include "rcu_test.h"
using namespace std;
RCUTest::RCUTest ()
: CppUnit::TestFixture ()
, _values (new Values)
{
}
CPPUNIT_TEST_SUITE_REGISTRATION (RCUTest);
void
RCUTest::setUp ()
{
if (!Glib::thread_supported ()) {
Glib::thread_init ();
}
}
static void*
launch_reader(void* self)
{
RCUTest* r = static_cast<RCUTest *>(self);
r->read_thread ();
return NULL;
}
static void*
launch_writer(void* self)
{
RCUTest* r = static_cast<RCUTest *>(self);
r->write_thread ();
return NULL;
}
void
RCUTest::race ()
{
pthread_barrier_init (&_barrier, NULL, 2);
pthread_t reader_thread;
pthread_t writer_thread;
CPPUNIT_ASSERT (pthread_create (&writer_thread, NULL, launch_writer, this) == 0);
CPPUNIT_ASSERT (pthread_create (&reader_thread, NULL, launch_reader, this) == 0);
void* return_value;
CPPUNIT_ASSERT (pthread_join (writer_thread, &return_value) == 0);
CPPUNIT_ASSERT (pthread_join (reader_thread, &return_value) == 0);
pthread_barrier_destroy (&_barrier);
}
/* ****************************************************************************/
void
RCUTest::read_thread ()
{
pthread_barrier_wait (&_barrier);
for (int i = 0; i < 15000; ++i) {
boost::shared_ptr<Values> reader = _values.reader ();
for (Values::const_iterator i = reader->begin (); i != reader->end(); ++i) {
CPPUNIT_ASSERT (i->first == i->second->val);
}
}
}
void
RCUTest::write_thread ()
{
pthread_barrier_wait (&_barrier);
for (int i = 0; i < 10000; ++i) {
RCUWriter<Values> writer (_values);
boost::shared_ptr<Values> w = writer.get_copy ();
char tmp [64];
sprintf (tmp, "foo %d", i);
w->insert (make_pair (tmp, new Value (tmp)));
}
/* replace */
for (int i = 0; i < 2500; ++i) {
RCUWriter<Values> writer (_values);
boost::shared_ptr<Values> w = writer.get_copy ();
char tmp [64];
sprintf (tmp, "foo %d", i);
Values::iterator x = w->find (tmp);
CPPUNIT_ASSERT (x != w->end ());
sprintf (tmp, "bar %d", i);
w->erase (x);
w->insert (make_pair (tmp, new Value (tmp)));
}
/* clear */
{
RCUWriter<Values> writer (_values);
boost::shared_ptr<Values> w = writer.get_copy ();
w->clear ();
}
_values.flush ();
}

35
libs/pbd/test/rcu_test.h Normal file
View File

@ -0,0 +1,35 @@
#include <string>
#include <pthread.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "pbd/rcu.h"
class RCUTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE (RCUTest);
CPPUNIT_TEST (race);
CPPUNIT_TEST_SUITE_END ();
public:
RCUTest ();
void setUp ();
void race ();
void read_thread ();
void write_thread ();
private:
class Value {
public:
Value (std::string const& v)
: val (v)
{}
std::string val;
};
typedef std::map<std::string, boost::shared_ptr<Value> > Values;
SerializedRCUManager<Values> _values;
pthread_barrier_t _barrier;
};

View File

@ -207,6 +207,7 @@ def build(bld):
test/convert_test.cc
test/filesystem_test.cc
test/natsort_test.cc
test/rcu_test.cc
test/reallocpool_test.cc
test/xml_test.cc
test/test_common.cc