Commit 79f27de3 authored by Pavel Vainerman's avatar Pavel Vainerman

(Mutex): Убрал механизм делающий write-lock более приориетным,

над read-lock в uniset_rwmutex-ах. Т.к. общая производительность очень сильно начинает зависеть от соотношения r/w.
parent 56368c31
...@@ -81,7 +81,7 @@ namespace UniSetTypes ...@@ -81,7 +81,7 @@ namespace UniSetTypes
}; };
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Mutex c приоритетом WRlock над RLock... // rwmutex..
class uniset_rwmutex class uniset_rwmutex
{ {
public: public:
...@@ -109,7 +109,6 @@ namespace UniSetTypes ...@@ -109,7 +109,6 @@ namespace UniSetTypes
std::string nm; std::string nm;
friend class uniset_rwmutex_lock; friend class uniset_rwmutex_lock;
ost::ThreadLock m; ost::ThreadLock m;
std::atomic<int> wr_wait;
static std::atomic<int> num; static std::atomic<int> num;
}; };
......
...@@ -79,7 +79,7 @@ uniset_mutex_lock::uniset_mutex_lock( uniset_mutex& m, const time_t timeMS ): ...@@ -79,7 +79,7 @@ uniset_mutex_lock::uniset_mutex_lock( uniset_mutex& m, const time_t timeMS ):
if( timeMS == 0 ) if( timeMS == 0 )
{ {
mutex->lock(); mutex->lock();
locked = 1; locked = true;
return; return;
} }
...@@ -93,17 +93,18 @@ uniset_mutex_lock::uniset_mutex_lock( uniset_mutex& m, const time_t timeMS ): ...@@ -93,17 +93,18 @@ uniset_mutex_lock::uniset_mutex_lock( uniset_mutex& m, const time_t timeMS ):
return; return;
} }
// здесь мы уже под защитой mutex..
locked = true; locked = true;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool uniset_mutex_lock::lock_ok() bool uniset_mutex_lock::lock_ok()
{ {
return locked; return locked.load();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
uniset_mutex_lock::~uniset_mutex_lock() uniset_mutex_lock::~uniset_mutex_lock()
{ {
if( locked ) if( locked)
{ {
mutex->unlock(); mutex->unlock();
locked = false; locked = false;
...@@ -111,14 +112,12 @@ uniset_mutex_lock::~uniset_mutex_lock() ...@@ -111,14 +112,12 @@ uniset_mutex_lock::~uniset_mutex_lock()
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
uniset_rwmutex::uniset_rwmutex( const std::string& name ): uniset_rwmutex::uniset_rwmutex( const std::string& name ):
nm(name), nm(name)
wr_wait(0)
{ {
} }
uniset_rwmutex::uniset_rwmutex(): uniset_rwmutex::uniset_rwmutex():
nm(""), nm("")
wr_wait(0)
{ {
} }
...@@ -138,49 +137,45 @@ const uniset_rwmutex &uniset_rwmutex::operator=( const uniset_rwmutex& r ) ...@@ -138,49 +137,45 @@ const uniset_rwmutex &uniset_rwmutex::operator=( const uniset_rwmutex& r )
if( this != &r ) if( this != &r )
{ {
lock(); lock();
MUTEX_DEBUG(cerr << "...copy mutex...(" << r.nm << " --> " << nm << ")" << endl;)
ostringstream s; ostringstream s;
s << r.nm << "." << (++num); s << r.nm << "." << (++num);
nm = s.str(); nm = s.str();
wr_wait = 0;
unlock(); unlock();
MUTEX_DEBUG(cerr << "...copy mutex..." << nm << endl;)
} }
return *this; return *this;
} }
uniset_rwmutex::uniset_rwmutex( const uniset_rwmutex& r ): uniset_rwmutex::uniset_rwmutex( const uniset_rwmutex& r )
nm(r.nm),
wr_wait(0)
{ {
if( this != &r )
{
lock();
MUTEX_DEBUG(cerr << "...copy constr mutex...(" << r.nm << " --> " << nm << ")" << endl;)
ostringstream s;
s << r.nm << "." << (++num);
nm = s.str();
unlock();
}
} }
void uniset_rwmutex::lock() void uniset_rwmutex::lock()
{ {
MUTEX_DEBUG(cerr << nm << " prepare Locked.." << endl;) MUTEX_DEBUG(cerr << nm << " prepare Locked.." << endl;)
wr_wait++;
m.writeLock(); m.writeLock();
wr_wait--;
MUTEX_DEBUG(cerr << nm << " Locked.." << endl;) MUTEX_DEBUG(cerr << nm << " Locked.." << endl;)
} }
void uniset_rwmutex::wrlock() void uniset_rwmutex::wrlock()
{ {
MUTEX_DEBUG(cerr << nm << " prepare WRLocked.." << endl;) MUTEX_DEBUG(cerr << nm << " prepare WRLocked.." << endl;)
wr_wait++;
m.writeLock(); m.writeLock();
wr_wait--;
MUTEX_DEBUG(cerr << nm << " WRLocked.." << endl;) MUTEX_DEBUG(cerr << nm << " WRLocked.." << endl;)
} }
void uniset_rwmutex::rlock() void uniset_rwmutex::rlock()
{ {
MUTEX_DEBUG(cerr << nm << " prepare RLocked.." << endl;) MUTEX_DEBUG(cerr << nm << " prepare RLocked.." << endl;)
while( wr_wait )
{
MUTEX_DEBUG( cerr << nm << " whait... WR=" << wr_wait << endl; )
msleep(2);
}
m.readLock(); m.readLock();
MUTEX_DEBUG(cerr << nm << " RLocked.." << endl;) MUTEX_DEBUG(cerr << nm << " RLocked.." << endl;)
} }
......
...@@ -9,12 +9,12 @@ using namespace std; ...@@ -9,12 +9,12 @@ using namespace std;
using namespace UniSetTypes; using namespace UniSetTypes;
uniset_mutex m; uniset_mutex m;
uniset_rwmutex m_spin; uniset_rwmutex m_rw;
class MyClass class MyClass
{ {
public: public:
MyClass( const std::string& name ): nm(name),count(0) MyClass( const std::string& name ): nm(name),term(false),count(0)
{ {
thr = new ThreadCreator<MyClass>(this, &MyClass::thread); thr = new ThreadCreator<MyClass>(this, &MyClass::thread);
} }
...@@ -29,6 +29,8 @@ class MyClass ...@@ -29,6 +29,8 @@ class MyClass
thr->start(); thr->start();
} }
void terminate() { term=true; }
inline std::string name(){ return nm; } inline std::string name(){ return nm; }
inline int lock_count(){ return count; } inline int lock_count(){ return count; }
...@@ -38,17 +40,16 @@ class MyClass ...@@ -38,17 +40,16 @@ class MyClass
protected: protected:
std::string nm; std::string nm;
std::atomic_bool term;
void thread() void thread()
{ {
while(1) while(!term)
{ {
{ {
uniset_mutex_lock l(m); uniset_mutex_lock l(m);
count++; count++;
msleep(30);
} }
msleep(10);
} }
} }
...@@ -60,7 +61,7 @@ class MyClass ...@@ -60,7 +61,7 @@ class MyClass
class MyClassSpin class MyClassSpin
{ {
public: public:
MyClassSpin( const std::string& name, bool rl=false ): nm(name),readLock(rl),count(0) MyClassSpin( const std::string& name, bool rl=false ): nm(name),readLock(rl),term(false),count(0)
{ {
thr = new ThreadCreator<MyClassSpin>(this, &MyClassSpin::thread); thr = new ThreadCreator<MyClassSpin>(this, &MyClassSpin::thread);
} }
...@@ -75,35 +76,36 @@ class MyClassSpin ...@@ -75,35 +76,36 @@ class MyClassSpin
thr->start(); thr->start();
} }
void terminate() { term=true; }
inline std::string name(){ return nm; } inline std::string name(){ return nm; }
inline int lock_count(){ return count; } inline int lock_count(){ return count; }
// BAD CODE... only for test..
inline ThreadCreator<MyClassSpin>* get(){ return thr; }
protected: protected:
std::string nm; std::string nm;
bool readLock; bool readLock;
std::atomic_bool term;
void thread() void thread()
{ {
while(1) while(!term)
{ {
if( !readLock ) if( !readLock )
{ {
// cerr << nm << ": before RWlock.." << endl; uniset_rwmutex_wrlock l(m_rw);
uniset_rwmutex_wrlock l(m_spin);
count++; count++;
msleep(30);
// cerr << nm << ": after RWlock.." << endl;
} }
else else
{ {
// cerr << nm << "(readLock): before lock.." << endl; uniset_rwmutex_rlock l(m_rw);
uniset_rwmutex_rlock l(m_spin);
count++; count++;
msleep(20);
// cerr << nm << "(readLock): after lock.." << endl;
} }
msleep(20); //msleep(20);
} }
} }
...@@ -139,6 +141,7 @@ int main( int argc, const char **argv ) ...@@ -139,6 +141,7 @@ int main( int argc, const char **argv )
{ {
try try
{ {
#if 0
{ {
cout << "check timed_mutex..." << endl; cout << "check timed_mutex..." << endl;
std::timed_mutex m; std::timed_mutex m;
...@@ -171,8 +174,8 @@ int main( int argc, const char **argv ) ...@@ -171,8 +174,8 @@ int main( int argc, const char **argv )
} }
} }
#endif
#if 1 #if 0
{ {
uniset_rwmutex m1("mutex1"); uniset_rwmutex m1("mutex1");
uniset_rwmutex m2("mutex2"); uniset_rwmutex m2("mutex2");
...@@ -229,6 +232,7 @@ int main( int argc, const char **argv ) ...@@ -229,6 +232,7 @@ int main( int argc, const char **argv )
m1.wrlock(); m1.wrlock();
return 0; return 0;
#endif #endif
#if 0 #if 0
uniset_mutex um; uniset_mutex um;
...@@ -289,65 +293,107 @@ int main( int argc, const char **argv ) ...@@ -289,65 +293,107 @@ int main( int argc, const char **argv )
msleep(50); msleep(50);
} }
cout << "TEST LOCK wait 10 sec.. (" << tvec.size() << " threads)" << endl; cout << "TEST MUTEX LOCK wait 10 sec.. (" << tvec.size() << " threads)" << endl;
msleep(10000); msleep(10000);
cout << "TEST LOCK RESULT: " << endl; cout << "TEST MUTEX LOCK RESULT: " << endl;
for( TVec::iterator it=tvec.begin(); it!=tvec.end(); it++ ) for( TVec::iterator it=tvec.begin(); it!=tvec.end(); it++ )
{ {
int c = (*it)->lock_count(); int c = (*it)->lock_count();
(*it)->get()->stop(); (*it)->terminate();
cout << (*it)->name() << ": locked counter: " << c << " " << ( c!=0 ? "OK":"FAIL" ) << endl; if( (*it)->get()->isRunning() )
(*it)->get()->join();
//(*it)->get()->stop();
cout << (*it)->name() << ": locked counter: " << (c/10) << " " << ( c!=0 ? "OK":"FAIL" ) << endl;
} }
#endif #endif
#if 1 #if 1
typedef std::vector<MyClassSpin*> TSpinVec; typedef std::vector<MyClassSpin*> TSpinVec;
TSpinVec tsvec(max); TSpinVec tsvec(max);
int half = 3; // max/2;
for( int i=0; i<max; i++ ) for( int i=0; i<max; i++ )
{ {
ostringstream s; ostringstream s;
bool r=false;
#if 1
if( i>=half )
{
r = true;
s << "(R)";
}
else
#endif
s << "(W)";
s << "t" << i; s << "t" << i;
MyClassSpin* t = new MyClassSpin(s.str());
MyClassSpin* t = new MyClassSpin(s.str(),r);
tsvec[i] = t; tsvec[i] = t;
t->execute(); t->execute();
msleep(50); msleep(20);
} }
cout << "TEST WRLOCK wait 10 sec.. (" << tsvec.size() << " threads)" << endl; cout << "TEST RWMUTEX LOCK wait 10 sec.. (" << tsvec.size() << " threads)" << endl;
msleep(10000); msleep(10000);
cout << "TEST WRLOCK RESULT: " << endl; cout << "TEST RWMUTEX LOCK RESULT: " << endl;
for( TSpinVec::iterator it=tsvec.begin(); it!=tsvec.end(); it++ ) for( TSpinVec::iterator it=tsvec.begin(); it!=tsvec.end(); it++ )
{ {
int c = (*it)->lock_count(); int c = (*it)->lock_count();
cout << (*it)->name() << ": locked counter: " << c << " " << ( c!=0 ? "OK":"FAIL" ) << endl; (*it)->terminate();
if( (*it)->get()->isRunning() )
(*it)->get()->join();
cout << (*it)->name() << ": locked counter: " << (c/10) << " " << ( c!=0 ? "OK":"FAIL" ) << endl;
} }
#endif #endif
#if 0 #if 0
typedef std::vector<MyClassSpin*> TSpinVec2;
TSpinVec2 tsvec2(max);
for( int i=0; i<max; i++ ) for( int i=0; i<max; i++ )
{ {
ostringstream s; ostringstream s;
s << "t" << i; s << "t" << i;
MyClassSpin* t = new MyClassSpin(s.str(),true); MyClassSpin* t = new MyClassSpin(s.str(),true);
tsvec[i] = t;
t->execute(); t->execute();
msleep(50); msleep(50);
} }
while(1) std::atomic_int cnt(0);
std::atomic_int num(10);
while( --num )
{ {
{ {
cerr << "(writeLock): ************* lock WAIT..." << endl; // cerr << "(writeLock): ************* lock WAIT..." << endl;
uniset_spin_wrlock l(m_spin); uniset_rwmutex_wrlock l(m_rw);
cerr << "(writeLock): ************* lock OK.." << endl; cnt++;
// cerr << "(writeLock): ************* lock OK.." << endl;
}
msleep(10);
} }
msleep(15); cout << "WRITE LOCK: " << cnt << endl;
for( auto &it: tsvec2 )
{
int c = it->lock_count();
it->terminate();
if( it->get()->isRunning() )
it->get()->join();
// cout << it->name() << ": locked counter: " << c << " " << ( c!=0 ? "OK":"FAIL" ) << endl;
} }
#endif #endif
// pause(); // pause();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment