00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <core/threading/spinlock.h>
00025 #include <core/threading/thread.h>
00026 #include <core/exception.h>
00027
00028 #include <pthread.h>
00029 #include <unistd.h>
00030
00031
00032 #if defined(_POSIX_SPIN_LOCKS) && (_POSIX_SPIN_LOCKS - 200112L) >= 0
00033 # define USE_POSIX_SPIN_LOCKS
00034 #else
00035 # undef USE_POSIX_SPIN_LOCKS
00036 # include <core/threading/mutex.h>
00037 #endif
00038
00039 namespace fawkes {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class SpinlockData
00061 {
00062 public:
00063 #ifdef USE_POSIX_SPIN_LOCKS
00064 pthread_spinlock_t spinlock;
00065 #else
00066 Mutex mutex;
00067 #endif
00068 };
00069
00070
00071
00072
00073 Spinlock::Spinlock()
00074 {
00075 spinlock_data = new SpinlockData();
00076 #ifdef USE_POSIX_SPIN_LOCKS
00077 pthread_spin_init(&(spinlock_data->spinlock), PTHREAD_PROCESS_PRIVATE);
00078 #endif
00079 }
00080
00081
00082 Spinlock::~Spinlock()
00083 {
00084 #ifdef USE_POSIX_SPIN_LOCKS
00085 pthread_spin_destroy(&(spinlock_data->spinlock));
00086 #endif
00087 delete spinlock_data;
00088 spinlock_data = NULL;
00089 }
00090
00091
00092
00093
00094
00095
00096 void
00097 Spinlock::lock()
00098 {
00099 #ifdef USE_POSIX_SPIN_LOCKS
00100 int err = 0;
00101 if ( (err = pthread_spin_lock(&(spinlock_data->spinlock))) != 0 ) {
00102 throw Exception(err, "Failed to aquire lock for thread %s", Thread::current_thread()->name());
00103 }
00104 #else
00105 bool locked = false;
00106 while ( ! locked ) {
00107 locked = spinlock_data->mutex.try_lock();
00108 }
00109 #endif
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 bool
00131 Spinlock::try_lock()
00132 {
00133 #ifdef USE_POSIX_SPIN_LOCKS
00134 if (pthread_spin_trylock(&(spinlock_data->spinlock)) == 0) {
00135 return true;
00136 } else {
00137 return false;
00138 }
00139 #else
00140 return spinlock_data->mutex.try_lock();
00141 #endif
00142 }
00143
00144
00145
00146 void
00147 Spinlock::unlock()
00148 {
00149 #ifdef USE_POSIX_SPIN_LOCKS
00150 pthread_spin_unlock(&(spinlock_data->spinlock));
00151 #else
00152 spinlock_data->mutex.unlock();
00153 #endif
00154 }
00155
00156
00157 }