A smart reference pointer, aka boost::intrusive_ptr.
Relies on the held object to implement ref() and unref() correctly. Serializable using boost.serialization.
#define TEST_RUNTIME 300 // seconds
#include <iostream>
#include <lunchbox/clock.h>
#include <lunchbox/refPtr.h>
#include <lunchbox/referenced.h>
#include <lunchbox/test.h>
#include <lunchbox/thread.h>
#include <boost/intrusive_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#define NTHREADS 24
#define NREFS 200000
{
public:
Foo() {}
private:
virtual ~Foo() {}
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive&, unsigned int)
{
}
};
FooPtr foo;
{
public:
virtual void run()
{
FooPtr myFoo;
for (size_t i = 0; i < NREFS; ++i)
{
myFoo = foo;
foo = myFoo;
myFoo = 0;
}
}
};
typedef boost::intrusive_ptr<Foo> BoostPtr;
BoostPtr bFoo;
{
public:
virtual void run()
{
BoostPtr myBoost;
for (size_t i = 0; i < NREFS; ++i)
{
myBoost = bFoo;
bFoo = myBoost;
myBoost = 0;
}
}
};
{
public:
Bar() {}
virtual ~Bar() {}
};
typedef boost::shared_ptr<Bar> BarPtr;
BarPtr bBar;
{
public:
virtual void run()
{
BarPtr myBar;
for (size_t i = 0; i < NREFS; ++i)
{
myBar = bBar;
bBar = myBar;
myBar.reset();
}
}
};
int main(int, char**)
{
foo = new Foo;
TestThread threads[NTHREADS];
for (size_t i = 0; i < NTHREADS; ++i)
TEST(threads[i].start());
for (size_t i = 0; i < NTHREADS; ++i)
TEST(threads[i].join());
std::cout << time << " ms for " << 3 * NREFS
<< " lunchbox::RefPtr operations"
<< " in " << NTHREADS << " threads ("
<< time / (3 * NREFS * NTHREADS) * 1000000 << "ns/op)"
<< std::endl;
TEST(foo->getRefCount() == 1);
bFoo = new Foo;
BThread bThreads[NTHREADS];
for (size_t i = 0; i < NTHREADS; ++i)
TEST(bThreads[i].start());
for (size_t i = 0; i < NTHREADS; ++i)
TEST(bThreads[i].join());
std::cout << bTime << " ms for " << 3 * NREFS
<< " boost::intrusive_ptr ops "
<< "in " << NTHREADS << " threads ("
<< bTime / (3 * NREFS * NTHREADS) * 1000000 << "ns/op)"
<< std::endl;
TEST(bFoo->getRefCount() == 1);
boost::intrusive_ptr<Foo> boostFoo(foo.get());
TEST(foo->getRefCount() == 2);
boostFoo = 0;
TEST(foo->getRefCount() == 1);
bBar = BarPtr(new Bar);
BarThread barThreads[NTHREADS];
for (size_t i = 0; i < NTHREADS; ++i)
TEST(barThreads[i].start());
for (size_t i = 0; i < NTHREADS; ++i)
TEST(barThreads[i].join());
std::cout << barTime << " ms for " << 3 * NREFS
<< " boost::shared_ptr ops in " << NTHREADS << " threads ("
<< barTime / (3 * NREFS * NTHREADS) * 1000000 << "ns/op)"
<< std::endl;
bBar = boost::make_shared<Bar>();
for (size_t i = 0; i < NTHREADS; ++i)
TEST(barThreads[i].start());
for (size_t i = 0; i < NTHREADS; ++i)
TEST(barThreads[i].join());
const float barTime2 = clock.
getTimef();
std::cout << barTime2 << " ms for " << 3 * NREFS
<< " boost::shared_ptr ops in " << NTHREADS << " threads ("
<< barTime2 / (3 * NREFS * NTHREADS) * 1000000
<< "ns/op) using make_shared" << std::endl;
foo = 0;
return EXIT_SUCCESS;
}