Intermodule singleton optimization for windows

[SVN r79515]
This commit is contained in:
Ion Gaztañaga
2012-07-14 21:55:37 +00:00
parent 31cef340d4
commit 41e6d09338
18 changed files with 237 additions and 338 deletions

View File

@@ -6615,6 +6615,14 @@ thank them:
[section:release_notes Release Notes]
[section:release_notes_boost_1_51_00 Boost 1.51 Release]
* Synchronous and asynchronous flushing for `mapped_region::flush`.
* Source & ABI breaking: Removed `get_offset` method from `mapped_region` as
it has no practical utility and `m_offset` member was not for anything else.
[endsect]
[section:release_notes_boost_1_50_00 Boost 1.50 Release]
* Fixed bugs

View File

@@ -34,8 +34,9 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/fully_mapped_file_test_d.exe"
OutputFile="$(OutDir)/mapped_file_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"

View File

@@ -47,8 +47,8 @@ inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
const int NANOSECONDS_PER_MILLISECOND = 1000000;
boost::xtime xt;
int ret = boost::xtime_get(&xt, boost::TIME_UTC_);
BOOST_INTERPROCES_CHECK(ret == static_cast<int>(boost::TIME_UTC_));(void)ret;
int ret = boost::xtime_get(&xt, boost::TIME_UTC);
BOOST_INTERPROCES_CHECK(ret == static_cast<int>(boost::TIME_UTC));(void)ret;
nsecs += xt.nsec;
msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
secs += msecs / MILLISECONDS_PER_SECOND;

View File

@@ -27,6 +27,13 @@ inline void get_process_id_name(std::string &str)
str = sstr.str().c_str();
}
inline void get_process_id_ptr_name(std::string &str, const void *ptr)
{
std::stringstream sstr;
sstr << "process_" << boost::interprocess::ipcdetail::get_current_process_id() << "_" << ptr << std::ends;
str = sstr.str().c_str();
}
inline const char *get_process_id_name()
{
static std::string str;
@@ -34,6 +41,13 @@ inline const char *get_process_id_name()
return str.c_str();
}
inline const char *get_process_id_ptr_name(void *ptr)
{
static std::string str;
get_process_id_ptr_name(str, ptr);
return str.c_str();
}
inline const char *add_to_process_id_name(const char *name)
{
static std::string str;
@@ -42,6 +56,14 @@ inline const char *add_to_process_id_name(const char *name)
return str.c_str();
}
inline const char *add_to_process_id_ptr_name(const char *name, void *ptr)
{
static std::string str;
get_process_id_ptr_name(str, ptr);
str += name;
return str.c_str();
}
} //namespace test{
} //namespace interprocess{
} //namespace boost{

View File

@@ -18,17 +18,17 @@ class MyClass
public:
MyClass()
{
std::cout << "Constructor\n";
std::cout << "MyClass()\n" << std::endl;
}
void shout() const
{
std::cout << "Shout\n";
std::cout << "Shout\n" << std::endl;
}
~MyClass()
{
std::cout << "Destructor\n";
std::cout << "~MyClass()\n" << std::endl;
}
};
@@ -101,6 +101,7 @@ class Logger
Logger()
{
++constructed_times;
std::cout << "Logger(),tag:" << typeid(Tag).name() << "(construct #" << constructed_times << ")\n" << std::endl;
}
void log_it()
@@ -109,6 +110,7 @@ class Logger
~Logger()
{
++destroyed_times;
std::cout << "~Logger(),tag:" << typeid(Tag).name() << "(destroy #" << destroyed_times << ")\n" << std::endl;
}
static unsigned int constructed_times;
@@ -130,13 +132,18 @@ class LogUser
{
public:
LogUser()
{}
{
std::cout << "LogUser(),tag:" << typeid(LogSingleton).name() << "\n" << std::endl;
}
void function_using_log()
{ LogSingleton::get().log_it(); }
~LogUser()
{ LogSingleton::get().log_it(); }
{
std::cout << "~LogUser(),tag:" << typeid(LogSingleton).name() << "\n" << std::endl;
LogSingleton::get().log_it();
}
};
//A class that tests the correct
@@ -147,7 +154,9 @@ class LogPhoenixTester
{
public:
LogPhoenixTester()
{}
{
std::cout << "LogPhoenixTester(), tag: " << typeid(Tag).name() << "\n" << std::endl;
}
void dummy()
{}
@@ -157,12 +166,24 @@ class LogPhoenixTester
//Test Phoenix singleton was correctly executed:
//created and destroyed two times
//This test will be executed after main ends
std::cout << "~LogPhoenixTester(), tag: " << typeid(Tag).name() << "\n" << std::endl;
if(Logger<Tag>::constructed_times != Logger<Tag>::destroyed_times ||
Logger<Tag>::constructed_times != 2)
{
std::string s("LogPhoenixTester failed for tag ");
s += typeid(Tag).name();
throw std::runtime_error(s.c_str());
std::stringstream sstr;
sstr << "LogPhoenixTester failed for tag ";
sstr << typeid(Tag).name();
sstr << "\n";
if(Logger<Tag>::constructed_times != 2){
sstr << "Logger<Tag>::constructed_times != 2\n";
sstr << "(";
sstr << Logger<Tag>::constructed_times << ")\n";
}
else{
sstr << "Logger<Tag>::constructed_times != Logger<Tag>::destroyed_times\n";
sstr << "(" << Logger<Tag>::constructed_times << " vs. " << Logger<Tag>::destroyed_times << ")\n";
}
throw std::runtime_error(sstr.str().c_str());
}
}
};
@@ -176,15 +197,18 @@ class LogDeadReferenceUser
{
public:
LogDeadReferenceUser()
{}
{
std::cout << "LogDeadReferenceUser(), LogSingleton: " << typeid(LogSingleton).name() << "\n" << std::endl;
}
void function_using_log()
{ LogSingleton::get().log_it(); }
~LogDeadReferenceUser()
{
std::cout << "~LogDeadReferenceUser(), LogSingleton: " << typeid(LogSingleton).name() << "\n" << std::endl;
//Make sure the exception is thrown as we are
//try to use a dead non-phoenix singleton
//trying to use a dead non-phoenix singleton
try{
LogSingleton::get().log_it();
std::string s("LogDeadReferenceUser failed for LogSingleton ");
@@ -254,30 +278,43 @@ int dead_reference_singleton_test()
return 0;
}
//reduce name length
template<typename C, bool LazyInit = true, bool Phoenix = true>
class port_singleton
: public ipcdetail::portable_intermodule_singleton<C, LazyInit, Phoenix>
{};
#ifdef BOOST_INTERPROCESS_WINDOWS
template<typename C, bool LazyInit = true, bool Phoenix = true>
class win_singleton
: public ipcdetail::windows_intermodule_singleton< C, LazyInit, Phoenix>
{};
#endif
int main ()
{
if(0 != intermodule_singleton_test<ipcdetail::portable_intermodule_singleton>()){
if(0 != intermodule_singleton_test<port_singleton>()){
return 1;
}
#ifdef BOOST_INTERPROCESS_WINDOWS
if(0 != intermodule_singleton_test<ipcdetail::windows_intermodule_singleton>()){
if(0 != intermodule_singleton_test<win_singleton>()){
return 1;
}
#endif
//Phoenix singletons are tested after main ends,
//LogPhoenixTester does the work
phoenix_singleton_test<ipcdetail::portable_intermodule_singleton>();
phoenix_singleton_test<port_singleton>();
#ifdef BOOST_INTERPROCESS_WINDOWS
phoenix_singleton_test<ipcdetail::windows_intermodule_singleton>();
phoenix_singleton_test<win_singleton>();
#endif
//Dead reference singletons are tested after main ends,
//LogDeadReferenceUser does the work
dead_reference_singleton_test<ipcdetail::portable_intermodule_singleton>();
dead_reference_singleton_test<port_singleton>();
#ifdef BOOST_INTERPROCESS_WINDOWS
dead_reference_singleton_test<ipcdetail::windows_intermodule_singleton>();
dead_reference_singleton_test<win_singleton>();
#endif
return 0;

View File

@@ -24,13 +24,13 @@ int main ()
#if defined(BOOST_INTERPROCESS_WINDOWS)
test::test_all_lock<ipcdetail::windows_mutex>();
test::test_all_mutex<true, ipcdetail::windows_mutex>();
test::test_all_mutex<ipcdetail::windows_mutex>();
test::test_all_lock<ipcdetail::spin_mutex>();
test::test_all_mutex<true, ipcdetail::spin_mutex>();
test::test_all_mutex<ipcdetail::spin_mutex>();
#endif
test::test_all_lock<interprocess_mutex>();
test::test_all_mutex<true, interprocess_mutex>();
test::test_all_mutex<interprocess_mutex>();
return 0;
}

View File

@@ -228,33 +228,24 @@ void timed_lock_and_sleep(void *arg, M &sm)
}
}
template<bool SameObject, typename M>
template<typename M>
void test_mutex_lock()
{
shared_val = 0;
M m1, m2;
M *pm1, *pm2;
if(SameObject){
pm1 = pm2 = &m1;
}
else{
pm1 = &m1;
pm2 = &m2;
}
M mtx;
data<M> d1(1);
data<M> d2(2);
// Locker one launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, *pm1));
boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(1*BaseSeconds));
// Locker two launches, but it won't hold the lock for 2*BaseSeconds seconds.
boost::thread tm2(thread_adapter<M>(&lock_and_sleep, &d2, *pm2));
boost::thread tm2(thread_adapter<M>(&lock_and_sleep, &d2, mtx));
//Wait completion
tm1.join();
@@ -265,21 +256,12 @@ void test_mutex_lock()
BOOST_INTERPROCES_CHECK(d2.m_value == 2);
}
template<bool SameObject, typename M>
template<typename M>
void test_mutex_lock_timeout()
{
shared_val = 0;
M m1, m2;
M *pm1, *pm2;
if(SameObject){
pm1 = pm2 = &m1;
}
else{
pm1 = &m1;
pm2 = &m2;
}
M mtx;
int wait_time_s = BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS / 1000;
if (wait_time_s == 0 )
@@ -289,13 +271,13 @@ void test_mutex_lock_timeout()
data<M> d2(2, wait_time_s * 2);
// Locker one launches, and holds the lock for wait_time_s * 2 seconds.
boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, *pm1));
boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(wait_time_s));
// Locker two launches, and attempts to hold the lock for wait_time_s * 2 seconds.
boost::thread tm2(thread_adapter<M>(&lock_and_catch_errors, &d2, *pm2));
boost::thread tm2(thread_adapter<M>(&lock_and_catch_errors, &d2, mtx));
//Wait completion
tm1.join();
@@ -308,33 +290,24 @@ void test_mutex_lock_timeout()
BOOST_INTERPROCES_CHECK(d2.m_error == boost::interprocess::timeout_when_locking_error);
}
template<bool SameObject, typename M>
template<typename M>
void test_mutex_try_lock()
{
shared_val = 0;
M m1, m2;
M *pm1, *pm2;
if(SameObject){
pm1 = pm2 = &m1;
}
else{
pm1 = &m1;
pm2 = &m2;
}
M mtx;
data<M> d1(1);
data<M> d2(2);
// Locker one launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm1(thread_adapter<M>(&try_lock_and_sleep, &d1, *pm1));
boost::thread tm1(thread_adapter<M>(&try_lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(1*BaseSeconds));
// Locker two launches, but it should fail acquiring the lock
boost::thread tm2(thread_adapter<M>(&try_lock_and_sleep, &d2, *pm2));
boost::thread tm2(thread_adapter<M>(&try_lock_and_sleep, &d2, mtx));
//Wait completion
tm1.join();
@@ -344,34 +317,25 @@ void test_mutex_try_lock()
BOOST_INTERPROCES_CHECK(d2.m_value == -1);
}
template<bool SameObject, typename M>
template<typename M>
void test_mutex_timed_lock()
{
shared_val = 0;
M m1, m2;
M *pm1, *pm2;
if(SameObject){
pm1 = pm2 = &m1;
}
else{
pm1 = &m1;
pm2 = &m2;
}
M mtx, m2;
data<M> d1(1, 2*BaseSeconds);
data<M> d2(2, 2*BaseSeconds);
// Locker one launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm1(thread_adapter<M>(&timed_lock_and_sleep, &d1, *pm1));
boost::thread tm1(thread_adapter<M>(&timed_lock_and_sleep, &d1, mtx));
//Wait 1*BaseSeconds
boost::thread::sleep(xsecs(1*BaseSeconds));
// Locker two launches, holds the lock for 2*BaseSeconds seconds.
boost::thread tm2(thread_adapter<M>(&timed_lock_and_sleep, &d2, *pm2));
boost::thread tm2(thread_adapter<M>(&timed_lock_and_sleep, &d2, mtx));
//Wait completion
tm1.join();
@@ -402,15 +366,15 @@ inline void test_all_recursive_lock()
test_recursive_lock<M>()();
}
template<bool SameObject, typename M>
template<typename M>
void test_all_mutex()
{
std::cout << "test_mutex_lock<" << typeid(M).name() << ">" << std::endl;
test_mutex_lock<SameObject, M>();
test_mutex_lock<M>();
std::cout << "test_mutex_try_lock<" << typeid(M).name() << ">" << std::endl;
test_mutex_try_lock<SameObject, M>();
test_mutex_try_lock<M>();
std::cout << "test_mutex_timed_lock<" << typeid(M).name() << ">" << std::endl;
test_mutex_timed_lock<SameObject, M>();
test_mutex_timed_lock<M>();
}
}}} //namespace boost { namespace interprocess { namespace test {

View File

@@ -21,8 +21,8 @@
int main ()
{
using namespace boost::interprocess;
test::test_mutex_lock_timeout<true, interprocess_mutex>();
test::test_mutex_lock_timeout<true, interprocess_recursive_mutex>();
test::test_mutex_lock_timeout<interprocess_mutex>();
test::test_mutex_lock_timeout<interprocess_recursive_mutex>();
return 0;
}

View File

@@ -14,6 +14,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/exceptions.hpp>
#include "boost_interprocess_check.hpp"
#include "get_process_id_name.hpp"
#include <iostream>
#include <typeinfo>
#include <boost/interprocess/creation_tags.hpp>
@@ -77,6 +78,53 @@ inline void test_named_creation()
dont_create_and_open<NamedResource>();
}
template<class NamedSync>
class named_sync_wrapper
: public NamedSync
{
public:
named_sync_wrapper()
: NamedSync(open_or_create, test::get_process_id_ptr_name(this))
{}
~named_sync_wrapper()
{
NamedSync::remove(test::get_process_id_ptr_name(this));
}
};
template<class NamedSync>
struct named_sync_deleter
{
~named_sync_deleter()
{ NamedSync::remove(test::get_process_id_name()); }
};
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
template<class NamedSync>
class named_sync_creation_test_wrapper
: public test::named_sync_deleter<NamedSync>, public NamedSync
{
public:
named_sync_creation_test_wrapper(create_only_t)
: NamedSync(create_only, test::get_process_id_name())
{}
named_sync_creation_test_wrapper(open_only_t)
: NamedSync(open_only, test::get_process_id_name())
{}
named_sync_creation_test_wrapper(open_or_create_t)
: NamedSync(open_or_create, test::get_process_id_name())
{}
~named_sync_creation_test_wrapper()
{}
};
}}} //namespace boost { namespace interprocess { namespace test {
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -14,78 +14,17 @@
#include "mutex_test_template.hpp"
#include "named_creation_template.hpp"
#include <string>
#include "get_process_id_name.hpp"
#include <boost/interprocess/detail/interprocess_tester.hpp>
using namespace boost::interprocess;
struct mutex_deleter
{
~mutex_deleter()
{ named_mutex::remove(test::get_process_id_name()); }
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_mutex_lock_test_wrapper
: public named_mutex
{
public:
named_mutex_lock_test_wrapper()
: named_mutex(open_or_create, test::get_process_id_name())
{ ++count_; }
~named_mutex_lock_test_wrapper()
{
if(--count_){
ipcdetail::interprocess_tester::
dont_close_on_destruction(static_cast<named_mutex&>(*this));
}
}
static int count_;
};
int named_mutex_lock_test_wrapper::count_ = 0;
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class named_mutex_creation_test_wrapper
: public mutex_deleter, public named_mutex
{
public:
named_mutex_creation_test_wrapper(create_only_t)
: named_mutex(create_only, test::get_process_id_name())
{ ++count_; }
named_mutex_creation_test_wrapper(open_only_t)
: named_mutex(open_only, test::get_process_id_name())
{ ++count_; }
named_mutex_creation_test_wrapper(open_or_create_t)
: named_mutex(open_or_create, test::get_process_id_name())
{ ++count_; }
~named_mutex_creation_test_wrapper()
{
if(--count_){
ipcdetail::interprocess_tester::
dont_close_on_destruction(static_cast<named_mutex&>(*this));
}
}
static int count_;
};
int named_mutex_creation_test_wrapper::count_ = 0;
int main ()
{
try{
named_mutex::remove(test::get_process_id_name());
test::test_named_creation<named_mutex_creation_test_wrapper>();
test::test_all_lock<named_mutex_lock_test_wrapper>();
test::test_all_mutex<false, named_mutex_lock_test_wrapper>();
test::test_named_creation< test::named_sync_creation_test_wrapper<named_mutex> >();
test::test_all_lock< test::named_sync_wrapper<named_mutex> >();
test::test_all_mutex<test::named_sync_wrapper<named_mutex> >();
}
catch(std::exception &ex){
named_mutex::remove(test::get_process_id_name());

View File

@@ -19,74 +19,14 @@
using namespace boost::interprocess;
struct mutex_deleter
{
~mutex_deleter()
{ named_recursive_mutex::remove(test::get_process_id_name()); }
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_recursive_mutex_lock_test_wrapper
: public named_recursive_mutex
{
public:
named_recursive_mutex_lock_test_wrapper()
: named_recursive_mutex(open_or_create, test::get_process_id_name())
{ ++count_; }
~named_recursive_mutex_lock_test_wrapper()
{
if(--count_){
ipcdetail::interprocess_tester::
dont_close_on_destruction(static_cast<named_recursive_mutex&>(*this));
}
}
static int count_;
};
int named_recursive_mutex_lock_test_wrapper::count_ = 0;
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class named_mutex_creation_test_wrapper
: public mutex_deleter, public named_recursive_mutex
{
public:
named_mutex_creation_test_wrapper(create_only_t)
: named_recursive_mutex(create_only, test::get_process_id_name())
{ ++count_; }
named_mutex_creation_test_wrapper(open_only_t)
: named_recursive_mutex(open_only, test::get_process_id_name())
{ ++count_; }
named_mutex_creation_test_wrapper(open_or_create_t)
: named_recursive_mutex(open_or_create, test::get_process_id_name())
{ ++count_; }
~named_mutex_creation_test_wrapper()
{
if(--count_){
ipcdetail::interprocess_tester::
dont_close_on_destruction(static_cast<named_recursive_mutex&>(*this));
}
}
static int count_;
};
int named_mutex_creation_test_wrapper::count_ = 0;
int main ()
{
try{
named_recursive_mutex::remove(test::get_process_id_name());
test::test_named_creation<named_mutex_creation_test_wrapper>();
test::test_all_lock<named_recursive_mutex_lock_test_wrapper>();
test::test_all_mutex<false, named_recursive_mutex_lock_test_wrapper>();
test::test_all_recursive_lock<named_recursive_mutex_lock_test_wrapper>();
test::test_named_creation< test::named_sync_creation_test_wrapper<named_recursive_mutex> >();
test::test_all_lock< test::named_sync_wrapper<named_recursive_mutex> >();
test::test_all_mutex<test::named_sync_wrapper<named_recursive_mutex> >();
test::test_all_recursive_lock<test::named_sync_wrapper<named_recursive_mutex> >();
}
catch(std::exception &ex){
named_recursive_mutex::remove(test::get_process_id_name());

View File

@@ -24,41 +24,27 @@ static const std::size_t SemCount = 1;
static const std::size_t RecSemCount = 100;
static const char * SemName = test::get_process_id_name();
struct semaphore_deleter
{
~semaphore_deleter()
{ named_semaphore::remove(SemName); }
};
//This wrapper is necessary to plug this class
//in named creation tests and interprocess_mutex tests
class named_semaphore_test_wrapper
: public semaphore_deleter, public named_semaphore
//in lock tests
class lock_test_wrapper
: public named_semaphore
{
public:
named_semaphore_test_wrapper()
: named_semaphore(open_or_create, SemName, SemCount)
{ ++count_; }
named_semaphore_test_wrapper(create_only_t)
: named_semaphore(create_only, SemName, SemCount)
{ ++count_; }
lock_test_wrapper(create_only_t, const char *name, unsigned int count = 1)
: named_semaphore(create_only, name, count)
{}
named_semaphore_test_wrapper(open_only_t)
: named_semaphore(open_only, SemName)
{ ++count_; }
lock_test_wrapper(open_only_t, const char *name)
: named_semaphore(open_only, name)
{}
named_semaphore_test_wrapper(open_or_create_t)
: named_semaphore(open_or_create, SemName, SemCount)
{ ++count_; }
lock_test_wrapper(open_or_create_t, const char *name, unsigned int count = 1)
: named_semaphore(open_or_create, name, count)
{}
~named_semaphore_test_wrapper()
{
if(--count_){
ipcdetail::interprocess_tester::
dont_close_on_destruction(static_cast<named_semaphore&>(*this));
}
}
~lock_test_wrapper()
{}
void lock()
{ this->wait(); }
@@ -71,31 +57,26 @@ class named_semaphore_test_wrapper
void unlock()
{ this->post(); }
protected:
named_semaphore_test_wrapper(int initial_count)
: named_semaphore(create_only, SemName, initial_count)
{}
static int count_;
};
int named_semaphore_test_wrapper::count_ = 0;
//This wrapper is necessary to plug this class
//in recursive tests
class recursive_named_semaphore_test_wrapper
: public named_semaphore_test_wrapper
class recursive_test_wrapper
: public lock_test_wrapper
{
public:
recursive_named_semaphore_test_wrapper()
: named_semaphore_test_wrapper(RecSemCount)
recursive_test_wrapper(create_only_t, const char *name)
: lock_test_wrapper(create_only, name, RecSemCount)
{}
static int count_;
};
recursive_test_wrapper(open_only_t, const char *name)
: lock_test_wrapper(open_only, name)
{}
int recursive_named_semaphore_test_wrapper::count_ = 0;
recursive_test_wrapper(open_or_create_t, const char *name)
: lock_test_wrapper(open_or_create, name, RecSemCount)
{}
};
bool test_named_semaphore_specific()
{
@@ -125,10 +106,10 @@ int main ()
{
try{
named_semaphore::remove(SemName);
test::test_named_creation<named_semaphore_test_wrapper>();
test::test_all_lock<named_semaphore_test_wrapper>();
test::test_all_recursive_lock<recursive_named_semaphore_test_wrapper>();
test::test_all_mutex<false, named_semaphore_test_wrapper>();
test::test_named_creation< test::named_sync_creation_test_wrapper<lock_test_wrapper> >();
test::test_all_lock< test::named_sync_wrapper<lock_test_wrapper> >();
test::test_all_mutex<test::named_sync_wrapper<lock_test_wrapper> >();
test::test_all_recursive_lock<test::named_sync_wrapper<recursive_test_wrapper> >();
test_named_semaphore_specific();
}
catch(std::exception &ex){

View File

@@ -86,10 +86,10 @@ int main ()
{
try{
named_upgradable_mutex::remove(test::get_process_id_name());
test::test_named_creation<named_upgradable_mutex_creation_test_wrapper>();
test::test_all_lock<named_upgradable_mutex_lock_test_wrapper>();
test::test_all_mutex<true, named_upgradable_mutex_lock_test_wrapper>();
test::test_all_sharable_mutex<true, named_upgradable_mutex_lock_test_wrapper>();
test::test_named_creation< test::named_sync_creation_test_wrapper<named_upgradable_mutex> >();
test::test_all_lock< test::named_sync_wrapper<named_upgradable_mutex> >();
test::test_all_mutex<test::named_sync_wrapper<named_upgradable_mutex> >();
test::test_all_sharable_mutex<test::named_sync_wrapper<named_upgradable_mutex> >();
}
catch(std::exception &ex){
named_upgradable_mutex::remove(test::get_process_id_name());

View File

@@ -24,16 +24,16 @@ int main ()
#if defined(BOOST_INTERPROCESS_WINDOWS)
//
test::test_all_lock<ipcdetail::windows_recursive_mutex>();
test::test_all_mutex<true, ipcdetail::windows_recursive_mutex>();
test::test_all_mutex<ipcdetail::windows_recursive_mutex>();
test::test_all_recursive_lock<ipcdetail::windows_recursive_mutex>();
//
test::test_all_lock<ipcdetail::spin_recursive_mutex>();
test::test_all_mutex<true, ipcdetail::spin_recursive_mutex>();
test::test_all_mutex<ipcdetail::spin_recursive_mutex>();
test::test_all_recursive_lock<ipcdetail::spin_recursive_mutex>();
#endif
//
test::test_all_lock<interprocess_recursive_mutex>();
test::test_all_mutex<true, interprocess_recursive_mutex>();
test::test_all_mutex<interprocess_recursive_mutex>();
test::test_all_recursive_lock<interprocess_recursive_mutex>();
return 0;

View File

@@ -63,7 +63,7 @@ int main ()
test::test_all_lock<semaphore_test_wrapper>();
test::test_all_recursive_lock<recursive_semaphore_test_wrapper>();
test::test_all_mutex<true, semaphore_test_wrapper>();
test::test_all_mutex<semaphore_test_wrapper>();
return 0;
}

View File

@@ -111,41 +111,30 @@ void timed_shared(void *arg, SM &sm)
}
}
template<bool SameObject, typename SM>
template<typename SM>
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;
}
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, *pm1));
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, *pm2));
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, *pm3));
boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, *pm4));
boost::thread thr1(thread_adapter<SM>(plain_shared,&s1, mtx));
boost::thread thr2(thread_adapter<SM>(plain_shared,&s2, mtx));
thr2.join();
thr1.join();
@@ -160,33 +149,23 @@ void test_plain_sharable_mutex()
{
shared_val = 0;
SM m1, m2, m3, m4;
SM *pm1, *pm2, *pm3, *pm4;
SM mtx;
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));
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,*pm3));
boost::thread tw2(thread_adapter<SM>(plain_exclusive,&e2,*pm4));
boost::thread tw1(thread_adapter<SM>(plain_exclusive,&e1, mtx));
boost::thread tw2(thread_adapter<SM>(plain_exclusive,&e2, mtx));
thr2.join();
thr1.join();
@@ -201,20 +180,11 @@ void test_plain_sharable_mutex()
}
}
template<bool SameObject, typename SM>
template<typename SM>
void test_try_sharable_mutex()
{
SM m1, m2, m3;
SM *pm1, *pm2, *pm3;
SM mtx;
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);
@@ -225,15 +195,15 @@ void test_try_sharable_mutex()
// Writer one launches, holds the lock for 3*BaseSeconds seconds.
boost::thread tw1(thread_adapter<SM>(try_exclusive,&e1,*pm1));
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,*pm2));
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,*pm3));
boost::thread tw2(thread_adapter<SM>(try_exclusive,&e2,mtx));
tw2.join();
thr1.join();
@@ -244,21 +214,10 @@ void test_try_sharable_mutex()
BOOST_INTERPROCES_CHECK(e2.m_value == -1); // Try would return w/o waiting
}
template<bool SameObject, typename SM>
template<typename SM>
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;
}
SM mtx;
data<SM> s1(1,1*BaseSeconds);
data<SM> s2(2,3*BaseSeconds);
data<SM> e1(3,3*BaseSeconds);
@@ -269,21 +228,21 @@ void test_timed_sharable_mutex()
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 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,*pm2));
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,*pm3));
boost::thread thr2(thread_adapter<SM>(timed_shared,&s2,*pm4));
boost::thread thr1(thread_adapter<SM>(timed_shared,&s1,mtx));
boost::thread thr2(thread_adapter<SM>(timed_shared,&s2,mtx));
tw1.join();
thr1.join();
@@ -296,17 +255,17 @@ void test_timed_sharable_mutex()
BOOST_INTERPROCES_CHECK(e2.m_value == -1);
}
template<bool SameObject, typename SM>
template<typename SM>
void test_all_sharable_mutex()
{
std::cout << "test_plain_sharable_mutex<" << SameObject << ", " << typeid(SM).name() << ">" << std::endl;
test_plain_sharable_mutex<SameObject, SM>();
std::cout << "test_plain_sharable_mutex<" << typeid(SM).name() << ">" << std::endl;
test_plain_sharable_mutex<SM>();
std::cout << "test_try_sharable_mutex<" << SameObject << ", " << typeid(SM).name() << ">" << std::endl;
test_try_sharable_mutex<SameObject, SM>();
std::cout << "test_try_sharable_mutex<" << typeid(SM).name() << ">" << std::endl;
test_try_sharable_mutex<SM>();
std::cout << "test_timed_sharable_mutex<" << SameObject << ", " << typeid(SM).name() << ">" << std::endl;
test_timed_sharable_mutex<SameObject, SM>();
std::cout << "test_timed_sharable_mutex<" << typeid(SM).name() << ">" << std::endl;
test_timed_sharable_mutex<SM>();
}

View File

@@ -23,8 +23,8 @@ int main ()
using namespace boost::interprocess;
test::test_all_lock<interprocess_upgradable_mutex>();
test::test_all_mutex<true, interprocess_upgradable_mutex>();
test::test_all_sharable_mutex<true, interprocess_upgradable_mutex>();
test::test_all_mutex<interprocess_upgradable_mutex>();
test::test_all_sharable_mutex<interprocess_upgradable_mutex>();
//Test lock transition
{

View File

@@ -63,7 +63,7 @@ inline bool in_range(const boost::posix_time::ptime& xt, int secs=1)
boost::xtime xsecs(int secs)
{
boost::xtime ret;
boost::xtime_get(&ret, boost::TIME_UTC_);
boost::xtime_get(&ret, boost::TIME_UTC);
ret.sec += secs;
return ret;
}