All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
lightMutex.h
Go to the documentation of this file.
1 /* lightMutex.h
2  */
3 #ifndef OSL_LIGHT_MUTEX_H
4 #define OSL_LIGHT_MUTEX_H
5 
6 #include "osl/oslConfig.h"
7 #ifdef PROFILE_MUTEX
8 # include "osl/misc/perfmon.h"
9 #endif
10 #include <boost/thread.hpp>
11 #include <boost/utility.hpp>
12 
13 namespace osl
14 {
15  namespace misc
16  {
17 #if defined OSL_USE_RACE_DETECTOR || defined _MSC_VER
18  typedef boost::mutex LightMutex;
19  typedef boost::mutex LightMutexChar;
20 #else
21  template <class Mutex>
22  class LightScopedLock : boost::noncopyable {
23  Mutex& m;
24  public:
25 #ifdef PROFILE_MUTEX
26  LightScopedLock(osl::misc::CounterPair &c,Mutex& m) :m(m){
27  c.count2();
28  while(!m.tryLock()){
29  for(int i=0;i<2;i++){
30  if(!m.waitLock(100)) break;
31  if(m.tryLock()) return;
32  }
33  c.count1();
34  boost::thread::yield();
35  }
36  }
37 #else
38  LightScopedLock(Mutex& m) :m(m){
39  m.lock();
40  }
41 #endif
43  m.unlock();
44  }
45  };
46 
47 
48  class LightMutex : boost::noncopyable {
49  volatile int data;
50  public:
52  class unlockable_lock;
53  LightMutex() :data(0) {}
54  bool tryLock(){
55  if(data!=0) return false;
56  int dummy;
57 #ifdef __GNUC__
58  asm __volatile__(" movl $1,%0" "\n\t"
59  " xchgl (%1),%0" "\n\t"
60  : "=&q"(dummy)
61  : "q"(&data)
62  : "cc");
63 #else
64 # error "not supported"
65 #endif
66  return dummy==0;
67  }
68  bool waitLock(int counter){
69  for(int i=0;i<counter;i++){
70 #ifdef __GNUC__
71  asm __volatile__(" pause" "\n\t");
72 #endif
73  if(data==0)
74  return true;
75  }
76  return false;
77  }
78  void lock(){
79  while(!tryLock()){
80  for(int i=0;i<2;i++){
81  if(!waitLock(100)) break;
82  if(tryLock()) return;
83  }
84  boost::thread::yield();
85  }
86  }
87  void unlock(){
88  data=0;
89  }
90  };
91 
93  class LightMutex::unlockable_lock : boost::noncopyable {
95  bool locked;
96  public:
98  m.lock();
99  }
101  unlock();
102  }
103  void unlock()
104  {
105  if (locked) {
106  locked = false;
107  m.unlock();
108  }
109  }
110  };
111 
112  class LightMutexChar : boost::noncopyable {
113  volatile char data;
114  public:
117  bool tryLock(){
118  if(data!=0) return false;
119  char dummy;
120 #ifdef __GNUC__
121  asm __volatile__(" movb $1,%0" "\n\t"
122  " xchgb (%1),%0" "\n\t"
123  : "=&q"(dummy)
124  : "q"(&data)
125  : "cc");
126 #else
127 # error "not supported"
128 #endif
129  return dummy==0;
130  }
131  bool waitLock(int counter){
132  for(int i=0;i<counter;i++){
133 #ifdef __GNUC__
134  asm __volatile__(" pause" "\n\t");
135 #endif
136  if(data==0)
137  return true;
138  }
139  return false;
140  }
141  void lock(){
142  while(!tryLock()){
143  for(int i=0;i<2;i++){
144  if(!waitLock(100)) break;
145  if(tryLock()) return;
146  }
147  boost::thread::yield();
148  }
149  }
150  void unlock(){
151  data=0;
152  }
153  };
154 #endif
155 
156 #ifdef PROFILE_MUTEX
157 # define SCOPED_LOCK(lock,m) \
158  static osl::misc::CounterPair c(__FILE__, __FUNCTION__, __LINE__); \
159  osl::misc::LightMutex::scoped_lock lock(c,m);
160 # define SCOPED_LOCK_CHAR(lock,m) \
161  static osl::misc::CounterPair c(__FILE__, __FUNCTION__, __LINE__); \
162  osl::misc::LightMutexChar::scoped_lock lock(c,m);
163 #else
164 # define SCOPED_LOCK(lock,m) \
165  osl::misc::LightMutex::scoped_lock lock(m);
166 # define SCOPED_LOCK_CHAR(lock,m) \
167  osl::misc::LightMutexChar::scoped_lock lock(m);
168 #endif
169  }
170  using misc::LightMutex;
171 }
172 #endif /* OSL_LIGHT_MUTEX_H */
173 // ;;; Local Variables:
174 // ;;; mode:c++
175 // ;;; c-basic-offset:2
176 // ;;; End:
177