Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
3b35d826
Commit
3b35d826
authored
Dec 13, 2013
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(Thread): Переделал spin_mutex-ы на R и WR mutex-ы..
parent
1ccb0aa5
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
384 additions
and
57 deletions
+384
-57
Mutex.h
include/Mutex.h
+40
-11
Mutex.cc
src/Various/Mutex.cc
+93
-41
umutex.cc
tests/umutex.cc
+251
-5
No files found.
include/Mutex.h
View file @
3b35d826
...
...
@@ -27,18 +27,17 @@
#include <string>
#include <omnithread.h>
#include <signal.h>
#include <cc++/thread.h>
// -----------------------------------------------------------------------------------------
namespace
UniSetTypes
{
typedef
volatile
sig_atomic_t
mutex_atomic_t
;
// typedef _Atomic_word mutex_atomic_t;
typedef
ost
::
AtomicCounter
mutex_atomic_t
;
/*! \class uniset_mutex
* \note Напрямую функциями \a lock() и \a unlock() лучше не пользоваться.
* Как пользоваться см. \ref MutexHowToPage
* \todo Проверить правильность конструкторов копирования и operator=
* \todo Проверить правильность конструкторов копирования и operator=
*/
class
uniset_mutex
{
...
...
@@ -51,10 +50,7 @@ namespace UniSetTypes
void
lock
();
void
unlock
();
inline
std
::
string
name
()
{
return
nm
;
};
inline
std
::
string
name
(){
return
nm
;
}
protected
:
...
...
@@ -93,6 +89,7 @@ namespace UniSetTypes
};
// -------------------------------------------------------------------------
// Mutex c приоритетом WRlock над RLock...
class
uniset_spin_mutex
{
public
:
...
...
@@ -102,25 +99,57 @@ namespace UniSetTypes
void
lock
(
int
check_pause_msec
=
1
);
void
unlock
();
void
wrlock
(
int
check_pause_msec
=
1
);
void
rlock
(
int
check_pause_msec
=
1
);
uniset_spin_mutex
(
const
uniset_spin_mutex
&
r
);
const
uniset_spin_mutex
&
operator
=
(
const
uniset_spin_mutex
&
r
);
private
:
friend
class
uniset_spin_lock
;
mutex_atomic_t
m
;
ost
::
ThreadLock
m
;
ost
::
AtomicCounter
wr_wait
;
};
// -------------------------------------------------------------------------
class
uniset_spin_lock
{
public
:
uniset_spin_lock
(
uniset_spin_mutex
&
m
,
int
check_pause_msec
=
1
);
uniset_spin_lock
(
uniset_spin_mutex
&
m
,
int
check_pause_msec
);
~
uniset_spin_lock
();
protected
:
uniset_spin_lock
(
uniset_spin_mutex
&
_m
)
:
m
(
_m
){}
uniset_spin_mutex
&
m
;
private
:
uniset_spin_lock
(
const
uniset_spin_lock
&
);
uniset_spin_lock
&
operator
=
(
const
uniset_spin_lock
&
);
uniset_spin_mutex
&
m
;
};
class
uniset_spin_wrlock
:
protected
uniset_spin_lock
{
public
:
uniset_spin_wrlock
(
uniset_spin_mutex
&
m
,
int
check_pause_msec
=
1
);
~
uniset_spin_wrlock
();
private
:
uniset_spin_wrlock
(
const
uniset_spin_wrlock
&
);
uniset_spin_wrlock
&
operator
=
(
const
uniset_spin_wrlock
&
);
};
class
uniset_spin_rlock
:
protected
uniset_spin_lock
{
public
:
uniset_spin_rlock
(
uniset_spin_mutex
&
m
,
int
check_pause_msec
=
5
);
~
uniset_spin_rlock
();
private
:
uniset_spin_rlock
(
const
uniset_spin_rlock
&
);
uniset_spin_rlock
&
operator
=
(
const
uniset_spin_rlock
&
);
};
// -------------------------------------------------------------------------
}
// end of UniSetTypes namespace
...
...
src/Various/Mutex.cc
View file @
3b35d826
...
...
@@ -31,62 +31,57 @@
using
namespace
std
;
using
namespace
UniSetTypes
;
// -----------------------------------------------------------------------------
static
mutex_atomic_t
mutex_atomic_read
(
mutex_atomic_t
*
m
){
return
(
*
m
);
}
static
mutex_atomic_t
mutex_atomic_set
(
mutex_atomic_t
*
m
,
int
val
){
return
(
*
m
)
=
val
;
}
//static void mutex_atomic_inc( mutex_atomic_t* m ){ (*m)++; }
//static void mutex_atomic_dec( mutex_atomic_t* m ){ (*m)--; }
// -----------------------------------------------------------------------------
uniset_mutex
::
uniset_mutex
()
:
cnd
(
0
),
nm
(
""
)
nm
(
""
),
locked
(
0
)
{
mutex_atomic_set
(
&
locked
,
0
);
cnd
=
new
omni_condition
(
&
mtx
);
}
// -----------------------------------------------------------------------------
uniset_mutex
::
uniset_mutex
(
string
name
)
:
nm
(
name
)
cnd
(
0
),
nm
(
name
),
locked
(
0
)
{
mutex_atomic_set
(
&
locked
,
0
);
cnd
=
new
omni_condition
(
&
mtx
);
}
// -----------------------------------------------------------------------------
uniset_mutex
::~
uniset_mutex
()
{
unlock
();
mutex_atomic_set
(
&
locked
,
0
);
delete
cnd
;
}
// -----------------------------------------------------------------------------
void
uniset_mutex
::
lock
()
{
sem
.
wait
();
mutex_atomic_set
(
&
locked
,
1
)
;
locked
=
1
;
}
// -----------------------------------------------------------------------------
void
uniset_mutex
::
unlock
()
{
mutex_atomic_set
(
&
locked
,
0
)
;
locked
=
0
;
sem
.
post
();
cnd
->
signal
();
}
// -----------------------------------------------------------------------------
bool
uniset_mutex
::
isRelease
()
{
return
!
(
bool
)
mutex_atomic_read
(
&
locked
)
;
return
!
locked
;
}
// -----------------------------------------------------------------------------
const
uniset_mutex
&
uniset_mutex
::
operator
=
(
const
uniset_mutex
&
r
)
{
if
(
this
!=
&
r
)
locked
=
r
.
locked
;
//
if( this != &r )
//
locked = r.locked;
return
*
this
;
}
// -----------------------------------------------------------------------------
uniset_mutex
::
uniset_mutex
(
const
uniset_mutex
&
r
)
:
cnd
(
0
),
nm
(
r
.
nm
)
nm
(
r
.
nm
),
locked
(
r
.
locked
)
{
cnd
=
new
omni_condition
(
&
mtx
);
}
...
...
@@ -98,7 +93,7 @@ uniset_mutex_lock::uniset_mutex_lock( uniset_mutex& m, int timeMS ):
if
(
timeMS
<=
0
||
mutex
->
isRelease
()
)
{
mutex
->
lock
();
m
utex_atomic_set
(
&
mlock
,
1
)
;
m
lock
=
1
;
return
;
}
...
...
@@ -114,27 +109,26 @@ uniset_mutex_lock::uniset_mutex_lock( uniset_mutex& m, int timeMS ):
<<
timeMS
<<
" msec для "
<<
mutex
->
name
()
<<
endl
;
}
m
utex_atomic_set
(
&
mlock
,
0
)
;
m
lock
=
0
;
mutex
->
mtx
.
unlock
();
return
;
// ресурс не захватываем
}
m
utex_atomic_set
(
&
mlock
,
1
)
;
m
lock
=
1
;
mutex
->
lock
();
mutex
->
mtx
.
unlock
();
}
// -----------------------------------------------------------------------------
bool
uniset_mutex_lock
::
lock_ok
()
{
return
(
bool
)
mutex_atomic_read
(
&
mlock
)
;
return
mlock
;
}
uniset_mutex_lock
::~
uniset_mutex_lock
()
{
if
(
m
utex_atomic_read
(
&
mlock
)
)
if
(
m
lock
)
{
m
utex_atomic_set
(
&
mlock
,
0
)
;
m
lock
=
0
;
mutex
->
unlock
();
}
}
...
...
@@ -144,14 +138,13 @@ uniset_mutex_lock& uniset_mutex_lock::operator=(const uniset_mutex_lock &r)
return
*
this
;
}
// -----------------------------------------------------------------------------
uniset_spin_mutex
::
uniset_spin_mutex
()
uniset_spin_mutex
::
uniset_spin_mutex
()
:
wr_wait
(
0
)
{
unlock
();
}
uniset_spin_mutex
::~
uniset_spin_mutex
()
{
unlock
();
}
const
uniset_spin_mutex
&
uniset_spin_mutex
::
operator
=
(
const
uniset_spin_mutex
&
r
)
...
...
@@ -164,26 +157,48 @@ const uniset_spin_mutex &uniset_spin_mutex::operator=( const uniset_spin_mutex&
uniset_spin_mutex
::
uniset_spin_mutex
(
const
uniset_spin_mutex
&
r
)
{
unlock
();
//
unlock();
}
void
uniset_spin_mutex
::
lock
(
int
check_pause_msec
)
{
while
(
mutex_atomic_read
(
&
m
)
!=
0
)
wr_wait
+=
1
;
while
(
!
m
.
tryWriteLock
()
)
{
if
(
check_pause_msec
>
0
)
msleep
(
check_pause_msec
);
}
wr_wait
-=
1
;
}
void
uniset_spin_mutex
::
wrlock
(
int
check_pause_msec
)
{
wr_wait
+=
1
;
while
(
!
m
.
tryWriteLock
()
)
{
if
(
check_pause_msec
>
0
)
msleep
(
check_pause_msec
);
}
wr_wait
-=
1
;
}
void
uniset_spin_mutex
::
rlock
(
int
check_pause_msec
)
{
while
(
wr_wait
>
0
)
msleep
(
check_pause_msec
);
while
(
!
m
.
tryReadLock
()
)
{
if
(
check_pause_msec
>
0
)
msleep
(
check_pause_msec
);
}
mutex_atomic_set
(
&
m
,
1
);
}
void
uniset_spin_mutex
::
unlock
()
{
m
utex_atomic_set
(
&
m
,
0
);
m
.
unlock
(
);
}
// -------------------------------------------------------------------------------------------
uniset_spin_lock
::
uniset_spin_lock
(
uniset_spin_mutex
&
_m
,
int
check_pause_msec
)
:
m
(
_m
)
m
(
_m
)
{
m
.
lock
(
check_pause_msec
);
}
...
...
@@ -193,19 +208,56 @@ uniset_spin_lock::~uniset_spin_lock()
m
.
unlock
();
}
uniset_spin_lock
::
uniset_spin_lock
(
const
uniset_spin_lock
&
r
)
:
m
(
r
.
m
)
uniset_spin_wrlock
::
uniset_spin_wrlock
(
uniset_spin_mutex
&
_m
,
int
check_pause_msec
)
:
uniset_spin_lock
(
_m
)
{
m
.
wrlock
(
check_pause_msec
);
}
uniset_spin_wrlock
::~
uniset_spin_wrlock
()
{
// unlocked in uniset_spin_lock destructor
}
uniset_spin_wrlock
::
uniset_spin_wrlock
(
const
uniset_spin_wrlock
&
r
)
:
uniset_spin_lock
(
r
.
m
)
{
}
uniset_spin_
lock
&
uniset_spin_lock
::
operator
=
(
const
uniset_spin_
lock
&
r
)
uniset_spin_
wrlock
&
uniset_spin_wrlock
::
operator
=
(
const
uniset_spin_wr
lock
&
r
)
{
if
(
this
!=
&
r
)
m
=
r
.
m
;
return
*
this
;
}
// -------------------------------------------------------------------------------------------
uniset_spin_rlock
::
uniset_spin_rlock
(
uniset_spin_mutex
&
_m
,
int
check_pause_msec
)
:
uniset_spin_lock
(
_m
)
{
m
.
rlock
(
check_pause_msec
);
}
uniset_spin_rlock
::~
uniset_spin_rlock
()
{
// unlocked in uniset_spin_lock destructor
}
uniset_spin_rlock
::
uniset_spin_rlock
(
const
uniset_spin_rlock
&
r
)
:
uniset_spin_lock
(
r
.
m
)
{
}
uniset_spin_rlock
&
uniset_spin_rlock
::
operator
=
(
const
uniset_spin_rlock
&
r
)
{
if
(
this
!=
&
r
)
m
=
r
.
m
;
return
*
this
;
}
// -----------------------------------------------------------------------------
#undef MUTEX_LOCK_SLEEP_MS
// -----------------------------------------------------------------------------
tests/umutex.cc
View file @
3b35d826
#include <string>
#include <sstream>
#include <vector>
#include "Mutex.h"
#include "ThreadCreator.h"
#include "UniSetTypes.h"
...
...
@@ -8,11 +9,12 @@ using namespace std;
using
namespace
UniSetTypes
;
uniset_mutex
m
;
uniset_spin_mutex
m_spin
;
class
MyClass
{
public
:
MyClass
(
const
std
::
string
&
name
)
:
nm
(
name
)
MyClass
(
const
std
::
string
&
name
)
:
nm
(
name
)
,
count
(
0
)
{
thr
=
new
ThreadCreator
<
MyClass
>
(
this
,
&
MyClass
::
thread
);
}
...
...
@@ -26,6 +28,13 @@ class MyClass
{
thr
->
start
();
}
inline
std
::
string
name
(){
return
nm
;
}
inline
int
lock_count
(){
return
count
;
}
// BAD CODE... only for test..
inline
ThreadCreator
<
MyClass
>*
get
(){
return
thr
;
}
protected
:
std
::
string
nm
;
...
...
@@ -35,10 +44,9 @@ class MyClass
while
(
1
)
{
{
cerr
<<
nm
<<
": before release="
<<
m
.
isRelease
()
<<
endl
;
uniset_mutex_lock
l
(
m
);
count
++
;
msleep
(
30
);
cerr
<<
nm
<<
": after release="
<<
m
.
isRelease
()
<<
endl
;
}
msleep
(
10
);
}
...
...
@@ -46,25 +54,263 @@ class MyClass
private
:
ThreadCreator
<
MyClass
>*
thr
;
int
count
;
};
class
MyClassSpin
{
public
:
MyClassSpin
(
const
std
::
string
&
name
,
bool
rl
=
false
)
:
nm
(
name
),
readLock
(
rl
),
count
(
0
)
{
thr
=
new
ThreadCreator
<
MyClassSpin
>
(
this
,
&
MyClassSpin
::
thread
);
}
~
MyClassSpin
()
{
delete
thr
;
}
void
execute
()
{
thr
->
start
();
}
inline
std
::
string
name
(){
return
nm
;
}
inline
int
lock_count
(){
return
count
;
}
protected
:
std
::
string
nm
;
bool
readLock
;
void
thread
()
{
while
(
1
)
{
if
(
!
readLock
)
{
// cerr << nm << ": before RWlock.." << endl;
uniset_spin_lock
l
(
m_spin
,
5
);
count
++
;
msleep
(
30
);
// cerr << nm << ": after RWlock.." << endl;
}
else
{
// cerr << nm << "(readLock): before lock.." << endl;
uniset_spin_rlock
l
(
m_spin
);
count
++
;
msleep
(
20
);
// cerr << nm << "(readLock): after lock.." << endl;
}
msleep
(
20
);
}
}
private
:
ThreadCreator
<
MyClassSpin
>*
thr
;
int
count
;
};
bool
check_wr_lock
(
ost
::
ThreadLock
&
m
)
{
if
(
m
.
tryWriteLock
()
)
{
m
.
unlock
();
return
true
;
}
return
false
;
}
bool
check_r_lock
(
ost
::
ThreadLock
&
m
)
{
if
(
m
.
tryReadLock
()
)
{
m
.
unlock
();
return
true
;
}
return
false
;
}
int
main
(
int
argc
,
const
char
**
argv
)
{
try
{
#if 0
ost::ThreadLock m;
// cout << "test unlock.." << endl;
// m.unlock();
cout << "read lock.." << endl;
m.readLock();
cerr << "test write lock: " << (check_wr_lock(m) ? "FAIL" : "OK [0]") << endl;
cerr << "test read lock: " << (check_r_lock(m) ? "OK [1]" : "FAIL") << endl;
cout << "unlock.." << endl;
m.unlock();
cerr << "test write lock: " << (check_wr_lock(m) ? "OK [1]" : "FAIL") << endl;
cerr << "test read lock: " << (check_r_lock(m) ? "OK [1]" : "FAIL") << endl;
cout << "write lock.." << endl;
m.writeLock();
cerr << "test write lock: " << (check_wr_lock(m) ? "FAIL" : "OK [0]") << endl;
cerr << "test read lock: " << (check_r_lock(m) ? "FAIL" : "OK [0]") << endl;
cerr << endl << "***** uniset_spin_mutex ***" << endl;
uniset_spin_mutex m1;
cout << "read lock.." << endl;
m1.rlock();
cerr << "test read lock: " << endl;
m1.rlock();
cerr << "test read lock: OK" << endl;
m1.unlock();
cerr << "test write lock.." << endl;
m1.wrlock();
return 0;
#endif
#if 0
uniset_mutex um;
cout << "lock.." << endl;
um.lock();
cerr << "test lock: " << ( !um.isRelease() ? "OK" : "FAIL") << endl;
um.unlock();
cerr << "test unlock: " << (um.isRelease() ? "OK" : "FAIL") << endl;
um.lock();
cerr << "test second lock: " << (!um.isRelease() ? "OK" : "FAIL") << endl;
/*
cerr << "test lock again.." << endl;
um.lock();
cerr << "test lock again FAIL" << endl;
*/
um.unlock();
cerr << "**** uniset_mutex_lock..." << endl;
{
uniset_mutex_lock l(um);
cerr << "test lock: " << ( !um.isRelease() ? "OK" : "FAIL") << endl;
}
cerr << "test unlock: " << (um.isRelease() ? "OK" : "FAIL") << endl;
{
uniset_mutex_lock l(um);
cerr << "test second lock: " << (!um.isRelease() ? "OK" : "FAIL") << endl;
uniset_mutex_lock l2(um,500);
cerr << "test wait lock: " << ( !l2.lock_ok() ? "OK" : "FAIL") << endl;
}
uniset_mutex_lock l3(um,500);
cerr << "test wait lock: " << ( l3.lock_ok() ? "OK" : "FAIL") << endl;
return 0;
#endif
int
max
=
10
;
if
(
argc
>
1
)
max
=
UniSetTypes
::
uni_atoi
(
argv
[
1
]);
#if 1
typedef
std
::
vector
<
MyClass
*>
TVec
;
TVec
tvec
(
max
);
for
(
int
i
=
0
;
i
<
max
;
i
++
)
{
ostringstream
s
;
s
<<
"t"
<<
i
;
MyClass
*
t
=
new
MyClass
(
s
.
str
());
tvec
[
i
]
=
t
;
t
->
execute
();
msleep
(
50
);
}
pause
();
cout
<<
"TEST LOCK wait 10 sec.. ("
<<
tvec
.
size
()
<<
" threads)"
<<
endl
;
msleep
(
10000
);
cout
<<
"TEST LOCK RESULT: "
<<
endl
;
for
(
TVec
::
iterator
it
=
tvec
.
begin
();
it
!=
tvec
.
end
();
it
++
)
{
int
c
=
(
*
it
)
->
lock_count
();
(
*
it
)
->
get
()
->
stop
();
cout
<<
(
*
it
)
->
name
()
<<
": locked counter: "
<<
c
<<
" "
<<
(
c
!=
0
?
"OK"
:
"FAIL"
)
<<
endl
;
}
#endif
#if 0
typedef std::vector<MyClassSpin*> TSpinVec;
TSpinVec tsvec(max);
for( int i=0; i<max; i++ )
{
ostringstream s;
s << "t" << i;
MyClassSpin* t = new MyClassSpin(s.str());
tsvec[i] = t;
t->execute();
msleep(50);
}
cout << "TEST WRLOCK wait 10 sec.. (" << tsvec.size() << " threads)" << endl;
msleep(10000);
cout << "TEST WRLOCK RESULT: " << endl;
for( TSpinVec::iterator it=tsvec.begin(); it!=tsvec.end(); it++ )
{
int c = (*it)->lock_count();
cout << (*it)->name() << ": locked counter: " << c << " " << ( c!=0 ? "OK":"FAIL" ) << endl;
}
#endif
#if 0
for( int i=0; i<max; i++ )
{
ostringstream s;
s << "t" << i;
MyClassSpin* t = new MyClassSpin(s.str(),true);
t->execute();
msleep(50);
}
while(1)
{
{
cerr << "(writeLock): ************* lock WAIT..." << endl;
uniset_spin_wrlock l(m_spin);
cerr << "(writeLock): ************* lock OK.." << endl;
}
msleep(15);
}
#endif
// pause();
}
catch
(
omniORB
::
fatalException
&
fe
)
{
cerr
<<
"поймали omniORB::fatalException:"
<<
endl
;
cerr
<<
" file: "
<<
fe
.
file
()
<<
endl
;
cerr
<<
" line: "
<<
fe
.
line
()
<<
endl
;
cerr
<<
" mesg: "
<<
fe
.
errmsg
()
<<
endl
;
}
catch
(
std
::
exception
&
e
)
{
cerr
<<
"catch: "
<<
e
.
what
()
<<
endl
;
}
catch
(...)
{
cerr
<<
"catch(...)"
<<
endl
;
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment