Changes in / [e5d9274:fc134a48]
- Files:
-
- 10 deleted
- 4 edited
-
libcfa/src/concurrency/invoke.h (modified) (3 diffs)
-
libcfa/src/concurrency/locks.cfa (modified) (1 diff)
-
libcfa/src/concurrency/locks.hfa (modified) (6 diffs)
-
libcfa/src/concurrency/thread.cfa (modified) (2 diffs)
-
tests/unified_locking/.expect/block_spin_lock.txt (deleted)
-
tests/unified_locking/.expect/clh.txt (deleted)
-
tests/unified_locking/.expect/mcs_block_spin_lock.txt (deleted)
-
tests/unified_locking/.expect/simple_owner_lock.txt (deleted)
-
tests/unified_locking/.expect/spin_queue_lock.txt (deleted)
-
tests/unified_locking/block_spin_lock.cfa (deleted)
-
tests/unified_locking/clh.cfa (deleted)
-
tests/unified_locking/mcs_block_spin_lock.cfa (deleted)
-
tests/unified_locking/simple_owner_lock.cfa (deleted)
-
tests/unified_locking/spin_queue_lock.cfa (deleted)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/invoke.h
re5d9274 rfc134a48 195 195 struct __monitor_group_t monitors; 196 196 197 // used to put threads on user data structures 198 struct { 199 struct thread$ * next; 200 struct thread$ * back; 201 } seqable; 202 197 203 // used to put threads on dlist data structure 198 204 __cfa_dlink(thread$); … … 202 208 struct thread$ * prev; 203 209 } node; 204 205 // used to store state between clh lock/unlock206 volatile bool * clh_prev;207 208 // used to point to this thd's current clh node209 volatile bool * clh_node;210 210 211 211 struct processor * last_proc; … … 240 240 } 241 241 242 static inline thread$ * volatile & ?`next ( thread$ * this ) __attribute__((const)) { 243 return this->seqable.next; 244 } 245 246 static inline thread$ *& Back( thread$ * this ) __attribute__((const)) { 247 return this->seqable.back; 248 } 249 250 static inline thread$ *& Next( thread$ * this ) __attribute__((const)) { 251 return this->seqable.next; 252 } 253 254 static inline bool listed( thread$ * this ) { 255 return this->seqable.next != 0p; 256 } 257 242 258 static inline void ?{}(__monitor_group_t & this) { 243 259 (this.data){0p}; -
libcfa/src/concurrency/locks.cfa
re5d9274 rfc134a48 178 178 179 179 //----------------------------------------------------------------------------- 180 // simple_owner_lock181 182 static inline void lock(simple_owner_lock & this) with(this) {183 if (owner == active_thread()) {184 recursion_count++;185 return;186 }187 lock( lock __cfaabi_dbg_ctx2 );188 189 if (owner != 0p) {190 insert_last( blocked_threads, *active_thread() );191 unlock( lock );192 park( );193 return;194 }195 owner = active_thread();196 recursion_count = 1;197 unlock( lock );198 }199 200 void pop_and_set_new_owner( simple_owner_lock & this ) with( this ) {201 thread$ * t = &try_pop_front( blocked_threads );202 owner = t;203 recursion_count = ( t ? 1 : 0 );204 unpark( t );205 }206 207 static inline void unlock(simple_owner_lock & this) with(this) {208 lock( lock __cfaabi_dbg_ctx2 );209 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );210 /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );211 // if recursion count is zero release lock and set new owner if one is waiting212 recursion_count--;213 if ( recursion_count == 0 ) {214 pop_and_set_new_owner( this );215 }216 unlock( lock );217 }218 219 static inline void on_notify(simple_owner_lock & this, struct thread$ * t ) with(this) {220 lock( lock __cfaabi_dbg_ctx2 );221 // lock held222 if ( owner != 0p ) {223 insert_last( blocked_threads, *t );224 unlock( lock );225 }226 // lock not held227 else {228 owner = t;229 recursion_count = 1;230 unpark( t );231 unlock( lock );232 }233 }234 235 static inline size_t on_wait(simple_owner_lock & this) with(this) {236 lock( lock __cfaabi_dbg_ctx2 );237 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );238 /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );239 240 size_t ret = recursion_count;241 242 pop_and_set_new_owner( this );243 244 unlock( lock );245 return ret;246 }247 248 static inline void on_wakeup(simple_owner_lock & this, size_t recursion ) with(this) { recursion_count = recursion; }249 250 251 //-----------------------------------------------------------------------------252 180 // alarm node wrapper 253 181 forall(L & | is_blocking_lock(L)) { -
libcfa/src/concurrency/locks.hfa
re5d9274 rfc134a48 98 98 mcs_node * next = advance(l.queue, &n); 99 99 if(next) post(next->sem); 100 }101 102 //-----------------------------------------------------------------------------103 // MCS Spin Lock104 // - No recursive acquisition105 // - Needs to be released by owner106 107 struct mcs_spin_node {108 mcs_spin_node * volatile next;109 bool locked:1;110 };111 112 struct mcs_spin_queue {113 mcs_spin_node * volatile tail;114 };115 116 static inline void ?{}(mcs_spin_node & this) { this.next = 0p; this.locked = true; }117 118 static inline mcs_spin_node * volatile & ?`next ( mcs_spin_node * node ) {119 return node->next;120 }121 122 struct mcs_spin_lock {123 mcs_spin_queue queue;124 };125 126 static inline void lock(mcs_spin_lock & l, mcs_spin_node & n) {127 mcs_spin_node * prev = __atomic_exchange_n(&l.queue.tail, &n, __ATOMIC_SEQ_CST);128 if(prev != 0p) {129 prev->next = &n;130 while(n.locked) Pause();131 }132 }133 134 static inline void unlock(mcs_spin_lock & l, mcs_spin_node & n) {135 mcs_spin_node * n_ptr = &n;136 if (!__atomic_compare_exchange_n(&l.queue.tail, &n_ptr, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {137 while (n.next == 0p) {}138 n.next->locked = false;139 }140 }141 142 //-----------------------------------------------------------------------------143 // CLH Spinlock144 // - No recursive acquisition145 // - Needs to be released by owner146 147 struct clh_lock {148 volatile bool * volatile tail;149 };150 151 static inline void ?{}( clh_lock & this ) { this.tail = malloc(); *this.tail = true; }152 static inline void ^?{}( clh_lock & this ) { free(this.tail); }153 154 static inline void lock(clh_lock & l) {155 thread$ * curr_thd = active_thread();156 *(curr_thd->clh_node) = false;157 volatile bool * prev = __atomic_exchange_n((bool **)(&l.tail), (bool *)(curr_thd->clh_node), __ATOMIC_SEQ_CST);158 while(!__atomic_load_n(prev, __ATOMIC_ACQUIRE)) Pause();159 curr_thd->clh_prev = prev;160 }161 162 static inline void unlock(clh_lock & l) {163 thread$ * curr_thd = active_thread();164 __atomic_store_n(curr_thd->clh_node, true, __ATOMIC_RELEASE);165 curr_thd->clh_node = curr_thd->clh_prev;166 100 } 167 101 … … 271 205 // Fast Block Lock 272 206 273 // minimal blocking lock207 // High efficiency minimal blocking lock 274 208 // - No reacquire for cond var 275 209 // - No recursive acquisition 276 210 // - No ownership 277 211 struct fast_block_lock { 212 // Spin lock used for mutual exclusion 213 __spinlock_t lock; 214 278 215 // List of blocked threads 279 216 dlist( thread$ ) blocked_threads; 280 217 281 // Spin lock used for mutual exclusion282 __spinlock_t lock;283 284 // flag showing if lock is held285 218 bool held:1; 286 287 #ifdef __CFA_DEBUG__288 // for deadlock detection289 struct thread$ * owner;290 #endif291 219 }; 292 220 … … 303 231 static inline void lock(fast_block_lock & this) with(this) { 304 232 lock( lock __cfaabi_dbg_ctx2 ); 305 306 #ifdef __CFA_DEBUG__307 assert(!(held && owner == active_thread()));308 #endif309 233 if (held) { 310 234 insert_last( blocked_threads, *active_thread() ); … … 314 238 } 315 239 held = true; 316 #ifdef __CFA_DEBUG__317 owner = active_thread();318 #endif319 240 unlock( lock ); 320 241 } … … 325 246 thread$ * t = &try_pop_front( blocked_threads ); 326 247 held = ( t ? true : false ); 327 #ifdef __CFA_DEBUG__328 owner = ( t ? t : 0p );329 #endif330 248 unpark( t ); 331 249 unlock( lock ); … … 335 253 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; } 336 254 static inline void on_wakeup(fast_block_lock & this, size_t recursion ) { } 337 338 //-----------------------------------------------------------------------------339 // simple_owner_lock340 341 // pthread owner lock342 // - reacquire for cond var343 // - recursive acquisition344 // - ownership345 struct simple_owner_lock {346 // List of blocked threads347 dlist( thread$ ) blocked_threads;348 349 // Spin lock used for mutual exclusion350 __spinlock_t lock;351 352 // owner showing if lock is held353 struct thread$ * owner;354 355 size_t recursion_count;356 };357 358 static inline void ?{}( simple_owner_lock & this ) with(this) {359 lock{};360 blocked_threads{};361 owner = 0p;362 recursion_count = 0;363 }364 static inline void ^?{}( simple_owner_lock & this ) {}365 static inline void ?{}( simple_owner_lock & this, simple_owner_lock this2 ) = void;366 static inline void ?=?( simple_owner_lock & this, simple_owner_lock this2 ) = void;367 368 //-----------------------------------------------------------------------------369 // Spin Queue Lock370 371 // - No reacquire for cond var372 // - No recursive acquisition373 // - No ownership374 // - spin lock with no locking/atomics in unlock375 struct spin_queue_lock {376 // Spin lock used for mutual exclusion377 mcs_spin_lock lock;378 379 // flag showing if lock is held380 bool held:1;381 382 #ifdef __CFA_DEBUG__383 // for deadlock detection384 struct thread$ * owner;385 #endif386 };387 388 static inline void ?{}( spin_queue_lock & this ) with(this) {389 lock{};390 held = false;391 }392 static inline void ^?{}( spin_queue_lock & this ) {}393 static inline void ?{}( spin_queue_lock & this, spin_queue_lock this2 ) = void;394 static inline void ?=?( spin_queue_lock & this, spin_queue_lock this2 ) = void;395 396 // if this is called recursively IT WILL DEADLOCK!!!!!397 static inline void lock(spin_queue_lock & this) with(this) {398 mcs_spin_node node;399 #ifdef __CFA_DEBUG__400 assert(!(held && owner == active_thread()));401 #endif402 lock( lock, node );403 while(held) Pause();404 held = true;405 unlock( lock, node );406 #ifdef __CFA_DEBUG__407 owner = active_thread();408 #endif409 }410 411 static inline void unlock(spin_queue_lock & this) with(this) {412 #ifdef __CFA_DEBUG__413 owner = 0p;414 #endif415 held = false;416 }417 418 static inline void on_notify(spin_queue_lock & this, struct thread$ * t ) { unpark(t); }419 static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; }420 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { }421 422 423 //-----------------------------------------------------------------------------424 // MCS Block Spin Lock425 426 // - No reacquire for cond var427 // - No recursive acquisition428 // - No ownership429 // - Blocks but first node spins (like spin queue but blocking for not first thd)430 struct mcs_block_spin_lock {431 // Spin lock used for mutual exclusion432 mcs_lock lock;433 434 // flag showing if lock is held435 bool held:1;436 437 #ifdef __CFA_DEBUG__438 // for deadlock detection439 struct thread$ * owner;440 #endif441 };442 443 static inline void ?{}( mcs_block_spin_lock & this ) with(this) {444 lock{};445 held = false;446 }447 static inline void ^?{}( mcs_block_spin_lock & this ) {}448 static inline void ?{}( mcs_block_spin_lock & this, mcs_block_spin_lock this2 ) = void;449 static inline void ?=?( mcs_block_spin_lock & this, mcs_block_spin_lock this2 ) = void;450 451 // if this is called recursively IT WILL DEADLOCK!!!!!452 static inline void lock(mcs_block_spin_lock & this) with(this) {453 mcs_node node;454 #ifdef __CFA_DEBUG__455 assert(!(held && owner == active_thread()));456 #endif457 lock( lock, node );458 while(held) Pause();459 held = true;460 unlock( lock, node );461 #ifdef __CFA_DEBUG__462 owner = active_thread();463 #endif464 }465 466 static inline void unlock(mcs_block_spin_lock & this) with(this) {467 #ifdef __CFA_DEBUG__468 owner = 0p;469 #endif470 held = false;471 }472 473 static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); }474 static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; }475 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) { }476 477 //-----------------------------------------------------------------------------478 // Block Spin Lock479 480 // - No reacquire for cond var481 // - No recursive acquisition482 // - No ownership483 // - Blocks but first node spins (like spin queue but blocking for not first thd)484 struct block_spin_lock {485 // Spin lock used for mutual exclusion486 fast_block_lock lock;487 488 // flag showing if lock is held489 bool held:1;490 491 #ifdef __CFA_DEBUG__492 // for deadlock detection493 struct thread$ * owner;494 #endif495 };496 497 static inline void ?{}( block_spin_lock & this ) with(this) {498 lock{};499 held = false;500 }501 static inline void ^?{}( block_spin_lock & this ) {}502 static inline void ?{}( block_spin_lock & this, block_spin_lock this2 ) = void;503 static inline void ?=?( block_spin_lock & this, block_spin_lock this2 ) = void;504 505 // if this is called recursively IT WILL DEADLOCK!!!!!506 static inline void lock(block_spin_lock & this) with(this) {507 #ifdef __CFA_DEBUG__508 assert(!(held && owner == active_thread()));509 #endif510 lock( lock );511 while(held) Pause();512 held = true;513 unlock( lock );514 #ifdef __CFA_DEBUG__515 owner = active_thread();516 #endif517 }518 519 static inline void unlock(block_spin_lock & this) with(this) {520 #ifdef __CFA_DEBUG__521 owner = 0p;522 #endif523 held = false;524 }525 526 static inline void on_notify(block_spin_lock & this, struct thread$ * t ) { unpark(t); }527 static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; }528 static inline void on_wakeup(block_spin_lock & this, size_t recursion ) { }529 255 530 256 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/thread.cfa
re5d9274 rfc134a48 53 53 #endif 54 54 55 seqable.next = 0p; 56 seqable.back = 0p; 57 55 58 node.next = 0p; 56 59 node.prev = 0p; 60 doregister(curr_cluster, this); 57 61 58 clh_node = malloc( );59 *clh_node = false;60 61 doregister(curr_cluster, this);62 62 monitors{ &self_mon_p, 1, (fptr_t)0 }; 63 63 } … … 67 67 canary = 0xDEADDEADDEADDEADp; 68 68 #endif 69 free(clh_node);70 69 unregister(curr_cluster, this); 71 70 ^self_cor{};
Note:
See TracChangeset
for help on using the changeset viewer.