Changes in libcfa/src/bits/locks.hfa [6ec07e5:e3fea42]
- File:
-
- 1 edited
-
libcfa/src/bits/locks.hfa (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/locks.hfa
r6ec07e5 re3fea42 54 54 55 55 #ifdef __CFA_DEBUG__ 56 void __cfaabi_dbg_record _lock(__spinlock_t & this, const char prev_name[]);56 void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]); 57 57 #else 58 #define __cfaabi_dbg_record _lock(x, y)58 #define __cfaabi_dbg_record(x, y) 59 59 #endif 60 60 } 61 62 extern void yield( unsigned int ); 61 63 62 64 static inline void ?{}( __spinlock_t & this ) { … … 66 68 // Lock the spinlock, return false if already acquired 67 69 static inline bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 68 disable_interrupts();69 70 bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0); 70 71 if( result ) { 71 __cfaabi_dbg_record_lock( this, caller ); 72 } else { 73 enable_interrupts_noPoll(); 72 disable_interrupts(); 73 __cfaabi_dbg_record( this, caller ); 74 74 } 75 75 return result; … … 83 83 #endif 84 84 85 disable_interrupts();86 85 for ( unsigned int i = 1;; i += 1 ) { 87 86 if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break; … … 99 98 #endif 100 99 } 101 __cfaabi_dbg_record_lock( this, caller ); 100 disable_interrupts(); 101 __cfaabi_dbg_record( this, caller ); 102 102 } 103 103 104 104 static inline void unlock( __spinlock_t & this ) { 105 enable_interrupts_noPoll(); 105 106 __atomic_clear( &this.lock, __ATOMIC_RELEASE ); 106 enable_interrupts_noPoll();107 107 } 108 108 … … 112 112 #endif 113 113 114 extern "C" {115 char * strerror(int);116 }117 #define CHECKED(x) { int err = x; if( err != 0 ) abort("KERNEL ERROR: Operation \"" #x "\" return error %d - %s\n", err, strerror(err)); }118 119 114 struct __bin_sem_t { 115 bool signaled; 120 116 pthread_mutex_t lock; 121 117 pthread_cond_t cond; 122 int val;123 118 }; 124 119 125 120 static inline void ?{}(__bin_sem_t & this) with( this ) { 126 // Create the mutex with error checking 127 pthread_mutexattr_t mattr; 128 pthread_mutexattr_init( &mattr ); 129 pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP); 130 pthread_mutex_init(&lock, &mattr); 131 132 pthread_cond_init (&cond, 0p); 133 val = 0; 121 signaled = false; 122 pthread_mutex_init(&lock, NULL); 123 pthread_cond_init (&cond, NULL); 134 124 } 135 125 136 126 static inline void ^?{}(__bin_sem_t & this) with( this ) { 137 CHECKED( pthread_mutex_destroy(&lock));138 CHECKED( pthread_cond_destroy (&cond));127 pthread_mutex_destroy(&lock); 128 pthread_cond_destroy (&cond); 139 129 } 140 130 141 131 static inline void wait(__bin_sem_t & this) with( this ) { 142 132 verify(__cfaabi_dbg_in_kernel()); 143 CHECKED( pthread_mutex_lock(&lock));144 while(val < 1) {133 pthread_mutex_lock(&lock); 134 if(!signaled) { // this must be a loop, not if! 145 135 pthread_cond_wait(&cond, &lock); 146 136 } 147 val -= 1;148 CHECKED( pthread_mutex_unlock(&lock));137 signaled = false; 138 pthread_mutex_unlock(&lock); 149 139 } 150 140 151 static inline boolpost(__bin_sem_t & this) with( this ) {152 bool needs_signal = false;141 static inline void post(__bin_sem_t & this) with( this ) { 142 verify(__cfaabi_dbg_in_kernel()); 153 143 154 CHECKED( pthread_mutex_lock(&lock) ); 155 if(val < 1) { 156 val += 1; 157 pthread_cond_signal(&cond); 158 needs_signal = true; 159 } 160 CHECKED( pthread_mutex_unlock(&lock) ); 144 pthread_mutex_lock(&lock); 145 bool needs_signal = !signaled; 146 signaled = true; 147 pthread_mutex_unlock(&lock); 161 148 162 return needs_signal; 149 if (needs_signal) 150 pthread_cond_signal(&cond); 163 151 } 164 165 #undef CHECKED166 152 #endif
Note:
See TracChangeset
for help on using the changeset viewer.