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