Changeset ac5816d
- Timestamp:
- Dec 27, 2020, 5:13:31 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 1e6f632f, b19fdb9
- Parents:
- c20533ea
- Location:
- libcfa/src/concurrency
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.cfa
rc20533ea rac5816d 5 5 #include <stdlib.hfa> 6 6 7 /////////////////////////////////////////////////////////////////// 8 //// info_thread 9 /////////////////////////////////////////////////////////////////// 10 7 //----------------------------------------------------------------------------- 8 // info_thread 11 9 forall(dtype L | is_blocking_lock(L)) { 12 void ?{}( info_thread(L) & this, $thread * t ) { 13 ((Seqable &) this){}; 14 this.t = t; 15 this.lock = 0p; 16 } 17 18 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) { 10 struct info_thread { 11 // used to put info_thread on a dl queue (aka sequence) 12 inline Seqable; 13 14 // waiting thread 15 struct $thread * t; 16 17 // shadow field 18 uintptr_t info; 19 20 // lock that is passed to wait() (if one is passed) 21 L * lock; 22 23 // true when signalled and false when timeout wakes thread 24 bool signalled; 25 }; 26 27 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info, L * l ) { 19 28 ((Seqable &) this){}; 20 29 this.t = t; 21 30 this.info = info; 22 this.lock = 0p;23 } 24 25 void ^?{}( info_thread(L) & this ) {}31 this.lock = l; 32 } 33 34 void ^?{}( info_thread(L) & this ) {} 26 35 27 36 info_thread(L) *& Back( info_thread(L) * this ) { … … 34 43 } 35 44 36 /////////////////////////////////////////////////////////////////// 37 //// Blocking Locks 38 /////////////////////////////////////////////////////////////////// 39 45 //----------------------------------------------------------------------------- 46 // Blocking Locks 40 47 void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ) { 41 48 this.lock{}; … … 49 56 50 57 void ^?{}( blocking_lock & this ) {} 51 void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}58 void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };} 52 59 void ^?{}( single_acquisition_lock & this ) {} 53 void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}60 void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };} 54 61 void ^?{}( owner_lock & this ) {} 55 void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}62 void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };} 56 63 void ^?{}( multiple_acquisition_lock & this ) {} 57 64 58 65 void lock( blocking_lock & this ) with( this ) { 59 66 lock( lock __cfaabi_dbg_ctx2 ); 60 if ( owner == active_thread() && !multi_acquisition) { // single acquisition lock is held by current thread 61 abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); 62 } else if ( owner != 0p && owner != active_thread() ) { // lock is held by some other thread 63 addTail( blocked_threads, *active_thread() ); 67 $thread * thrd = active_thread(); 68 69 // single acquisition lock is held by current thread 70 /* paranoid */ verifyf( owner != thrd || multi_acquisition, "Single acquisition lock holder (%p) attempted to reacquire the lock %p resulting in a deadlock.", owner, &this ); 71 72 // lock is held by some other thread 73 if ( owner != 0p && owner != thrd ) { 74 addTail( blocked_threads, *thrd ); 64 75 wait_count++; 65 76 unlock( lock ); 66 77 park( ); 67 } else if ( owner == active_thread() && multi_acquisition ) { // multi acquisition lock is held by current thread 78 } 79 // multi acquisition lock is held by current thread 80 else if ( owner == thrd && multi_acquisition ) { 68 81 recursion_count++; 69 82 unlock( lock ); 70 } else { // lock isn't held 71 owner = active_thread(); 83 } 84 // lock isn't held 85 else { 86 owner = thrd; 72 87 recursion_count = 1; 73 88 unlock( lock ); … … 78 93 bool ret = false; 79 94 lock( lock __cfaabi_dbg_ctx2 ); 80 if ( owner == 0p ) { // lock isn't held 95 96 // lock isn't held 97 if ( owner == 0p ) { 81 98 owner = active_thread(); 82 99 recursion_count = 1; 83 100 ret = true; 84 } else if ( owner == active_thread() && multi_acquisition ) { // multi acquisition lock is held by current thread 101 } 102 // multi acquisition lock is held by current thread 103 else if ( owner == active_thread() && multi_acquisition ) { 85 104 recursion_count++; 86 105 ret = true; 87 106 } 107 88 108 unlock( lock ); 89 109 return ret; 90 }91 92 void unlock_error_check( blocking_lock & this ) with( this ) {93 if ( owner == 0p ){ // lock isn't held94 abort( "There was an attempt to release a lock that isn't held" );95 } else if ( strict_owner && owner != active_thread() ) {96 abort( "A thread other than the owner attempted to release an owner lock" );97 }98 110 } 99 111 … … 108 120 void unlock( blocking_lock & this ) with( this ) { 109 121 lock( lock __cfaabi_dbg_ctx2 ); 110 unlock_error_check( this ); 122 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); 123 /* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 124 125 // if recursion count is zero release lock and set new owner if one is waiting 111 126 recursion_count--; 112 if ( recursion_count == 0 ) { // if recursion count is zero release lock and set new owner if one is waiting127 if ( recursion_count == 0 ) { 113 128 pop_and_set_new_owner( this ); 114 129 } … … 129 144 130 145 void on_notify( blocking_lock & this, $thread * t ) with( this ) { 131 lock( lock __cfaabi_dbg_ctx2 ); 132 if ( owner != 0p ) { // lock held 146 lock( lock __cfaabi_dbg_ctx2 ); 147 // lock held 148 if ( owner != 0p ) { 133 149 addTail( blocked_threads, *t ); 134 150 wait_count++; 135 151 unlock( lock ); 136 } else { // lock not held 152 } 153 // lock not held 154 else { 137 155 owner = t; 138 156 recursion_count = 1; … … 143 161 144 162 void on_wait( blocking_lock & this ) with( this ) { 145 lock( lock __cfaabi_dbg_ctx2 ); 146 unlock_error_check( this ); 163 lock( lock __cfaabi_dbg_ctx2 ); 164 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); 165 /* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 166 147 167 pop_and_set_new_owner( this ); 148 168 unlock( lock ); 149 169 } 150 170 151 /////////////////////////////////////////////////////////////////// 152 //// Overloaded routines for traits 153 /////////////////////////////////////////////////////////////////// 154 171 //----------------------------------------------------------------------------- 172 // Overloaded routines for traits 155 173 // These routines are temporary until an inheritance bug is fixed 156 157 void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); } 158 void unlock( single_acquisition_lock & this ){ unlock( (blocking_lock &)this ); } 159 void on_notify( single_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); } 160 void on_wait( single_acquisition_lock & this ){ on_wait( (blocking_lock &)this ); } 161 void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); } 162 size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } 163 164 void lock( owner_lock & this ){ lock( (blocking_lock &)this ); } 165 void unlock( owner_lock & this ){ unlock( (blocking_lock &)this ); } 166 void on_notify( owner_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); } 167 void on_wait( owner_lock & this ){ on_wait( (blocking_lock &)this ); } 168 void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); } 169 size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } 170 171 void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); } 172 void unlock( multiple_acquisition_lock & this ){ unlock( (blocking_lock &)this ); } 173 void on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); } 174 void on_wait( multiple_acquisition_lock & this ){ on_wait( (blocking_lock &)this ); } 175 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); } 174 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 ); } 176 193 size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } 177 194 178 195 //----------------------------------------------------------------------------- 196 // alarm node wrapper 179 197 forall(dtype L | is_blocking_lock(L)) { 180 198 struct alarm_node_wrap { … … 184 202 }; 185 203 186 void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback ) {204 void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback, condition_variable(L) * c, info_thread(L) * i ) { 187 205 this.alarm_node{ callback, alarm, period }; 206 this.cond = c; 207 this.i = i; 188 208 } 189 209 … … 191 211 192 212 void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) { 193 // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin. 194 lock( cond->lock __cfaabi_dbg_ctx2 ); 195 196 // this check is necessary to avoid a race condition since this timeout handler 197 // may still be called after a thread has been removed from the queue but 198 // before the alarm is unregistered 199 if ( listed(i) ) { // is thread on queue 200 i->signalled = false; 201 remove( cond->blocked_threads, *i ); // remove this thread O(1) 213 // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin. 214 lock( cond->lock __cfaabi_dbg_ctx2 ); 215 216 // this check is necessary to avoid a race condition since this timeout handler 217 // may still be called after a thread has been removed from the queue but 218 // before the alarm is unregistered 219 if ( listed(i) ) { // is thread on queue 220 i->signalled = false; 221 // remove this thread O(1) 222 remove( cond->blocked_threads, *i ); 202 223 cond->count--; 203 224 if( i->lock ) { 204 on_notify(*i->lock, i->t); // call lock's on_notify if a lock was passed 205 } else { 206 unpark( i->t ); // otherwise wake thread 207 } 208 } 209 unlock( cond->lock ); 225 // call lock's on_notify if a lock was passed 226 on_notify(*i->lock, i->t); 227 } else { 228 // otherwise wake thread 229 unpark( i->t ); 230 } 231 } 232 unlock( cond->lock ); 210 233 } 211 234 212 235 // this casts the alarm node to our wrapped type since we used type erasure 213 236 void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); } 214 215 } 216 217 /////////////////////////////////////////////////////////////////// 218 //// condition variable 219 /////////////////////////////////////////////////////////////////// 220 237 } 238 239 //----------------------------------------------------------------------------- 240 // condition variable 221 241 forall(dtype L | is_blocking_lock(L)) { 222 242 … … 234 254 count--; 235 255 if (popped.lock) { 236 on_notify(*popped.lock, popped.t); // if lock passed call on_notify 256 // if lock passed call on_notify 257 on_notify(*popped.lock, popped.t); 237 258 } else { 238 unpark(popped.t); // otherwise wake thread 259 // otherwise wake thread 260 unpark(popped.t); 239 261 } 240 262 } … … 268 290 269 291 size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) { 270 addTail( blocked_threads, *i ); // add info_thread to waiting queue 292 // add info_thread to waiting queue 293 addTail( blocked_threads, *i ); 271 294 count++; 272 295 size_t recursion_count = 0; 273 if (i->lock) { // if lock was passed get recursion count to reset to after waking thread 296 if (i->lock) { 297 // if lock was passed get recursion count to reset to after waking thread 274 298 recursion_count = get_recursion_count(*i->lock); 275 299 on_wait( *i->lock ); … … 283 307 size_t recursion_count = queue_and_get_recursion(this, &i); 284 308 unlock( lock ); 285 park( ); // blocks here 286 if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking 287 } 309 310 // blocks here 311 park( ); 312 313 // resets recursion count here after waking 314 if (i.lock) set_recursion_count(*i.lock, recursion_count); 315 } 316 317 #define WAIT( u, l ) \ 318 info_thread( L ) i = { active_thread(), u, l }; \ 319 queue_info_thread( this, i ); 288 320 289 321 // helper for wait()'s' with a timeout … … 291 323 lock( lock __cfaabi_dbg_ctx2 ); 292 324 size_t recursion_count = queue_and_get_recursion(this, &info); 293 alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast }; 294 node_wrap.cond = &this; 295 node_wrap.i = &info; 325 alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast, &this, &info }; 296 326 register_self( &node_wrap.alarm_node ); 297 327 unlock( lock ); 328 329 // blocks here 298 330 park(); 299 unregister_self( &node_wrap.alarm_node ); // unregisters alarm so it doesn't go off if this happens first 300 if (info.lock) set_recursion_count(*info.lock, recursion_count); // resets recursion count here after waking 301 } 302 303 void wait( condition_variable(L) & this ) with(this) { 304 info_thread( L ) i = { active_thread() }; 305 queue_info_thread( this, i ); 306 } 307 308 void wait( condition_variable(L) & this, uintptr_t info ) with(this) { 309 info_thread( L ) i = { active_thread(), info }; 310 queue_info_thread( this, i ); 311 } 312 313 bool wait( condition_variable(L) & this, Duration duration ) with(this) { 314 info_thread( L ) i = { active_thread() }; 315 queue_info_thread_timeout(this, i, __kernel_get_time() + duration ); 331 332 // unregisters alarm so it doesn't go off if this happens first 333 unregister_self( &node_wrap.alarm_node ); 334 335 // resets recursion count here after waking 336 if (info.lock) set_recursion_count(*info.lock, recursion_count); 337 } 338 339 #define WAIT_TIME( u, l, t ) \ 340 info_thread( L ) i = { active_thread(), u, l }; \ 341 queue_info_thread_timeout(this, i, t ); \ 316 342 return i.signalled; 317 } 318 319 bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { 320 info_thread( L ) i = { active_thread(), info }; 321 queue_info_thread_timeout(this, i, __kernel_get_time() + duration ); 322 return i.signalled; 323 } 324 325 bool wait( condition_variable(L) & this, Time time ) with(this) { 326 info_thread( L ) i = { active_thread() }; 327 queue_info_thread_timeout(this, i, time); 328 return i.signalled; 329 } 330 331 bool wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) { 332 info_thread( L ) i = { active_thread(), info }; 333 queue_info_thread_timeout(this, i, time); 334 return i.signalled; 335 } 336 337 void wait( condition_variable(L) & this, L & l ) with(this) { 338 info_thread(L) i = { active_thread() }; 339 i.lock = &l; 340 queue_info_thread( this, i ); 341 } 342 343 void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) { 344 info_thread(L) i = { active_thread(), info }; 345 i.lock = &l; 346 queue_info_thread( this, i ); 347 } 348 349 bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) { 350 info_thread(L) i = { active_thread() }; 351 i.lock = &l; 352 queue_info_thread_timeout(this, i, __kernel_get_time() + duration ); 353 return i.signalled; 354 } 355 356 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { 357 info_thread(L) i = { active_thread(), info }; 358 i.lock = &l; 359 queue_info_thread_timeout(this, i, __kernel_get_time() + duration ); 360 return i.signalled; 361 } 362 363 bool wait( condition_variable(L) & this, L & l, Time time ) with(this) { 364 info_thread(L) i = { active_thread() }; 365 i.lock = &l; 366 queue_info_thread_timeout(this, i, time ); 367 return i.signalled; 368 } 369 370 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) { 371 info_thread(L) i = { active_thread(), info }; 372 i.lock = &l; 373 queue_info_thread_timeout(this, i, time ); 374 return i.signalled; 375 } 376 } 343 344 void wait( condition_variable(L) & this ) with(this) { WAIT( 0, 0p ) } 345 void wait( condition_variable(L) & this, uintptr_t info ) with(this) { WAIT( info, 0p ) } 346 void wait( condition_variable(L) & this, L & l ) with(this) { WAIT( 0, &l ) } 347 void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) { WAIT( info, &l ) } 348 349 bool wait( condition_variable(L) & this, Duration duration ) with(this) { WAIT_TIME( 0 , 0p , __kernel_get_time() + duration ) } 350 bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, 0p , __kernel_get_time() + duration ) } 351 bool wait( condition_variable(L) & this, Time time ) with(this) { WAIT_TIME( 0 , 0p , time ) } 352 bool wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) { WAIT_TIME( info, 0p , time ) } 353 bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) { WAIT_TIME( 0 , &l , __kernel_get_time() + duration ) } 354 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , __kernel_get_time() + duration ) } 355 bool wait( condition_variable(L) & this, L & l, Time time ) with(this) { WAIT_TIME( 0 , &l , time ) } 356 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) { WAIT_TIME( info, &l , time ) } 357 } -
libcfa/src/concurrency/locks.hfa
rc20533ea rac5816d 10 10 #include "time_t.hfa" 11 11 #include "time.hfa" 12 #include <sys/time.h>13 12 14 /////////////////////////////////////////////////////////////////// 15 //// is_blocking_lock 16 /////////////////////////////////////////////////////////////////// 13 //----------------------------------------------------------------------------- 14 // is_blocking_lock 15 trait is_blocking_lock(dtype L | sized(L)) { 16 // For synchronization locks to use when acquiring 17 void on_notify( L &, struct $thread * ); 17 18 18 trait is_blocking_lock(dtype L | sized(L)) { 19 void on_notify( L &, struct $thread * ); // For synchronization locks to use when acquiring 20 void on_wait( L & ); // For synchronization locks to use when releasing 21 size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking 22 void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled; 19 // For synchronization locks to use when releasing 20 void on_wait( L & ); 21 22 // to get recursion count for cond lock to reset after waking 23 size_t get_recursion_count( L & ); 24 25 // to set recursion count after getting signalled; 26 void set_recursion_count( L &, size_t recursion ); 23 27 }; 24 28 25 /////////////////////////////////////////////////////////////////// 26 //// info_thread 27 /////////////////////////////////////////////////////////////////// 28 29 //----------------------------------------------------------------------------- 30 // info_thread 29 31 // the info thread is a wrapper around a thread used 30 32 // to store extra data for use in the condition variable 31 33 forall(dtype L | is_blocking_lock(L)) { 32 struct info_thread { 33 inline Seqable; // used to put info_thread on a dl queue (aka sequence) 34 struct $thread * t; // waiting thread 35 uintptr_t info; // shadow field 36 L * lock; // lock that is passed to wait() (if one is passed) 37 bool signalled; // true when signalled and false when timeout wakes thread 38 }; 39 40 41 void ?{}( info_thread(L) & this, $thread * t ); 42 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ); 43 void ^?{}( info_thread(L) & this ); 34 struct info_thread; 44 35 45 36 // for use by sequence … … 48 39 } 49 40 50 /////////////////////////////////////////////////////////////////// 51 //// Blocking Locks 52 /////////////////////////////////////////////////////////////////// 53 41 //----------------------------------------------------------------------------- 42 // Blocking Locks 54 43 struct blocking_lock { 55 44 // Spin lock used for mutual exclusion … … 87 76 }; 88 77 89 void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );78 void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ); 90 79 void ^?{}( blocking_lock & this ); 91 80 92 void ?{}( single_acquisition_lock & this );81 void ?{}( single_acquisition_lock & this ); 93 82 void ^?{}( single_acquisition_lock & this ); 94 83 95 void ?{}( owner_lock & this );84 void ?{}( owner_lock & this ); 96 85 void ^?{}( owner_lock & this ); 97 86 98 void ?{}( multiple_acquisition_lock & this );87 void ?{}( multiple_acquisition_lock & this ); 99 88 void ^?{}( multiple_acquisition_lock & this ); 100 89 … … 129 118 size_t get_recursion_count( multiple_acquisition_lock & this ); 130 119 131 /////////////////////////////////////////////////////////////////// 132 //// Synchronization Locks 133 /////////////////////////////////////////////////////////////////// 120 //----------------------------------------------------------------------------- 121 // Synchronization Locks 134 122 forall(dtype L | is_blocking_lock(L)) { 135 123 struct condition_variable { … … 144 132 }; 145 133 146 void ?{}( condition_variable(L) & this );134 void ?{}( condition_variable(L) & this ); 147 135 void ^?{}( condition_variable(L) & this ); 148 136 … … 152 140 uintptr_t front( condition_variable(L) & this ); 153 141 154 bool empty ( condition_variable(L) & this );155 int counter( condition_variable(L) & this );142 bool empty ( condition_variable(L) & this ); 143 int counter( condition_variable(L) & this ); 156 144 157 145 void wait( condition_variable(L) & this ); -
libcfa/src/concurrency/thread.cfa
rc20533ea rac5816d 133 133 134 134 this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP]; 135 verify( this_thrd->context.SP );135 /* paranoid */ verify( this_thrd->context.SP ); 136 136 137 137 __schedule_thread( this_thrd );
Note: See TracChangeset
for help on using the changeset viewer.