- File:
-
- 1 edited
-
libcfa/src/concurrency/locks.cfa (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.cfa
rc18bf9e r305aaef 24 24 #include <stdlib.hfa> 25 25 26 #pragma GCC visibility push(default)27 28 26 //----------------------------------------------------------------------------- 29 27 // info_thread … … 118 116 } 119 117 120 staticvoid pop_and_set_new_owner( blocking_lock & this ) with( this ) {118 void pop_and_set_new_owner( blocking_lock & this ) with( this ) { 121 119 thread$ * t = &try_pop_front( blocked_threads ); 122 120 owner = t; … … 176 174 recursion_count = recursion; 177 175 } 176 177 //----------------------------------------------------------------------------- 178 // simple_owner_lock 179 180 static inline void lock(simple_owner_lock & this) with(this) { 181 if (owner == active_thread()) { 182 recursion_count++; 183 return; 184 } 185 lock( lock __cfaabi_dbg_ctx2 ); 186 187 if (owner != 0p) { 188 insert_last( blocked_threads, *active_thread() ); 189 unlock( lock ); 190 park( ); 191 return; 192 } 193 owner = active_thread(); 194 recursion_count = 1; 195 unlock( lock ); 196 } 197 198 void pop_and_set_new_owner( simple_owner_lock & this ) with( this ) { 199 thread$ * t = &try_pop_front( blocked_threads ); 200 owner = t; 201 recursion_count = ( t ? 1 : 0 ); 202 unpark( t ); 203 } 204 205 static inline void unlock(simple_owner_lock & this) with(this) { 206 lock( lock __cfaabi_dbg_ctx2 ); 207 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); 208 /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 209 // if recursion count is zero release lock and set new owner if one is waiting 210 recursion_count--; 211 if ( recursion_count == 0 ) { 212 pop_and_set_new_owner( this ); 213 } 214 unlock( lock ); 215 } 216 217 static inline void on_notify(simple_owner_lock & this, struct thread$ * t ) with(this) { 218 lock( lock __cfaabi_dbg_ctx2 ); 219 // lock held 220 if ( owner != 0p ) { 221 insert_last( blocked_threads, *t ); 222 unlock( lock ); 223 } 224 // lock not held 225 else { 226 owner = t; 227 recursion_count = 1; 228 unpark( t ); 229 unlock( lock ); 230 } 231 } 232 233 static inline size_t on_wait(simple_owner_lock & this) with(this) { 234 lock( lock __cfaabi_dbg_ctx2 ); 235 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); 236 /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 237 238 size_t ret = recursion_count; 239 240 pop_and_set_new_owner( this ); 241 242 unlock( lock ); 243 return ret; 244 } 245 246 static inline void on_wakeup(simple_owner_lock & this, size_t recursion ) with(this) { recursion_count = recursion; } 247 178 248 179 249 //----------------------------------------------------------------------------- … … 194 264 void ^?{}( alarm_node_wrap(L) & this ) { } 195 265 196 staticvoid timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {266 void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) { 197 267 // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin. 198 268 lock( cond->lock __cfaabi_dbg_ctx2 ); … … 218 288 219 289 // this casts the alarm node to our wrapped type since we used type erasure 220 staticvoid alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }290 void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); } 221 291 } 222 292 … … 235 305 void ^?{}( condition_variable(L) & this ){ } 236 306 237 staticvoid process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {307 void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) { 238 308 if(&popped != 0p) { 239 309 popped.signalled = true; … … 280 350 int counter( condition_variable(L) & this ) with(this) { return count; } 281 351 282 s tatic size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {352 size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) { 283 353 // add info_thread to waiting queue 284 354 insert_last( blocked_threads, *i ); … … 293 363 294 364 // helper for wait()'s' with no timeout 295 staticvoid queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {365 void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) { 296 366 lock( lock __cfaabi_dbg_ctx2 ); 297 367 size_t recursion_count = queue_and_get_recursion(this, &i); … … 310 380 311 381 // helper for wait()'s' with a timeout 312 staticvoid queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {382 void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 313 383 lock( lock __cfaabi_dbg_ctx2 ); 314 384 size_t recursion_count = queue_and_get_recursion(this, &info); … … 345 415 // fast_cond_var 346 416 void ?{}( fast_cond_var(L) & this ){ 347 this.blocked_threads{}; 417 this.blocked_threads{}; 348 418 #ifdef __CFA_DEBUG__ 349 419 this.lock_used = 0p;
Note:
See TracChangeset
for help on using the changeset viewer.