Changeset 8e4aa05 for libcfa/src/concurrency/locks.cfa
- Timestamp:
- Mar 4, 2021, 7:40:25 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 77d601f
- Parents:
- 342af53 (diff), a5040fe (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.cfa
r342af53 r8e4aa05 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo 3 // 4 // The contents of this file are covered under the licence agreement in the 5 // file "LICENCE" distributed with Cforall. 6 // 7 // locks.hfa -- LIBCFATHREAD 8 // Runtime locks that used with the runtime thread system. 9 // 10 // Author : Colby Alexander Parsons 11 // Created On : Thu Jan 21 19:46:50 2021 12 // Last Modified By : 13 // Last Modified On : 14 // Update Count : 15 // 16 17 #define __cforall_thread__ 18 1 19 #include "locks.hfa" 2 20 #include "kernel_private.hfa" … … 7 25 //----------------------------------------------------------------------------- 8 26 // info_thread 9 forall( dtype L| is_blocking_lock(L)) {27 forall(L & | is_blocking_lock(L)) { 10 28 struct info_thread { 11 29 // used to put info_thread on a dl queue (aka sequence) … … 56 74 57 75 void ^?{}( blocking_lock & this ) {} 58 void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };} 59 void ^?{}( single_acquisition_lock & this ) {} 60 void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };} 61 void ^?{}( owner_lock & this ) {} 62 void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };} 63 void ^?{}( multiple_acquisition_lock & this ) {} 76 64 77 65 78 void lock( blocking_lock & this ) with( this ) { … … 170 183 171 184 //----------------------------------------------------------------------------- 172 // Overloaded routines for traits173 // These routines are temporary until an inheritance bug is fixed174 void lock ( single_acquisition_lock & this ) { lock ( (blocking_lock &)this ); }175 void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }176 void on_wait ( single_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }177 void on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }178 void set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }179 size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }180 181 void lock ( owner_lock & this ) { lock ( (blocking_lock &)this ); }182 void unlock ( owner_lock & this ) { unlock ( (blocking_lock &)this ); }183 void on_wait ( owner_lock & this ) { on_wait( (blocking_lock &)this ); }184 void on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }185 void set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }186 size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }187 188 void lock ( multiple_acquisition_lock & this ) { lock ( (blocking_lock &)this ); }189 void unlock ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }190 void on_wait ( multiple_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }191 void on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }192 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }193 size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }194 195 //-----------------------------------------------------------------------------196 185 // alarm node wrapper 197 forall( dtype L| is_blocking_lock(L)) {186 forall(L & | is_blocking_lock(L)) { 198 187 struct alarm_node_wrap { 199 188 alarm_node_t alarm_node; … … 239 228 //----------------------------------------------------------------------------- 240 229 // condition variable 241 forall( dtype L| is_blocking_lock(L)) {230 forall(L & | is_blocking_lock(L)) { 242 231 243 232 void ?{}( condition_variable(L) & this ){ … … 356 345 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) { WAIT_TIME( info, &l , time ) } 357 346 } 347 348 //----------------------------------------------------------------------------- 349 // Semaphore 350 void ?{}( semaphore & this, int count = 1 ) { 351 (this.lock){}; 352 this.count = count; 353 (this.waiting){}; 354 } 355 void ^?{}(semaphore & this) {} 356 357 bool P(semaphore & this) with( this ){ 358 lock( lock __cfaabi_dbg_ctx2 ); 359 count -= 1; 360 if ( count < 0 ) { 361 // queue current task 362 append( waiting, active_thread() ); 363 364 // atomically release spin lock and block 365 unlock( lock ); 366 park(); 367 return true; 368 } 369 else { 370 unlock( lock ); 371 return false; 372 } 373 } 374 375 bool V(semaphore & this) with( this ) { 376 $thread * thrd = 0p; 377 lock( lock __cfaabi_dbg_ctx2 ); 378 count += 1; 379 if ( count <= 0 ) { 380 // remove task at head of waiting list 381 thrd = pop_head( waiting ); 382 } 383 384 unlock( lock ); 385 386 // make new owner 387 unpark( thrd ); 388 389 return thrd != 0p; 390 } 391 392 bool V(semaphore & this, unsigned diff) with( this ) { 393 $thread * thrd = 0p; 394 lock( lock __cfaabi_dbg_ctx2 ); 395 int release = max(-count, (int)diff); 396 count += diff; 397 for(release) { 398 unpark( pop_head( waiting ) ); 399 } 400 401 unlock( lock ); 402 403 return thrd != 0p; 404 }
Note:
See TracChangeset
for help on using the changeset viewer.