Changeset db6f06a for src/libcfa/concurrency/kernel.c
- Timestamp:
- Feb 13, 2017, 5:04:43 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- ee897e4b
- Parents:
- 75f3522
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r75f3522 rdb6f06a 141 141 } 142 142 143 void start(processor * this);144 145 143 void ?{}(processor * this) { 146 144 this{ systemCluster }; … … 151 149 this->current_coroutine = NULL; 152 150 this->current_thread = NULL; 153 (&this-> lock){};154 this-> terminated = false;151 (&this->terminated){}; 152 this->is_terminated = false; 155 153 156 154 start( this ); … … 161 159 this->current_coroutine = NULL; 162 160 this->current_thread = NULL; 163 (&this-> lock){};164 this-> terminated = false;161 (&this->terminated){}; 162 this->is_terminated = false; 165 163 166 164 this->runner = runner; … … 170 168 171 169 void ^?{}(processor * this) { 172 if( ! this-> terminated ) {170 if( ! this->is_terminated ) { 173 171 LIB_DEBUG_PRINTF("Kernel : core %p signaling termination\n", this); 174 this-> terminated = true;175 lock( &this->lock);172 this->is_terminated = true; 173 wait( &this->terminated ); 176 174 } 177 175 } … … 194 192 LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this); 195 193 196 fenv_t envp;197 fegetenv( &envp );198 LIB_DEBUG_PRINTF("Kernel : mxcsr %x\n", envp.__mxcsr);199 200 194 thread * readyThread = NULL; 201 for( unsigned int spin_count = 0; ! this-> terminated; spin_count++ )195 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 202 196 { 203 197 readyThread = nextThread( this->cltr ); … … 208 202 209 203 //Some actions need to be taken from the kernel 210 finishRunning(this , readyThread);204 finishRunning(this); 211 205 212 206 spin_count = 0; … … 219 213 220 214 LIB_DEBUG_PRINTF("Kernel : core %p unlocking thread\n", this); 221 unlock( &this->lock);215 signal( &this->terminated ); 222 216 LIB_DEBUG_PRINTF("Kernel : core %p terminated\n", this); 223 217 } … … 230 224 231 225 //Reset the terminating actions here 232 this-> thread_action = NoAction;226 this->finish.action_code = No_Action; 233 227 234 228 //Update global state … … 242 236 // Once a thread has finished running, some of 243 237 // its final actions must be executed from the kernel 244 void finishRunning(processor * this, thread * thrd) { 245 if(this->thread_action == Reschedule) { 246 ScheduleThread( thrd ); 238 void finishRunning(processor * this) { 239 if( this->finish.action_code == Release ) { 240 unlock( this->finish.lock ); 241 } 242 else if( this->finish.action_code == Schedule ) { 243 ScheduleThread( this->finish.thrd ); 244 } 245 else if( this->finish.action_code == Release_Schedule ) { 246 unlock( this->finish.lock ); 247 ScheduleThread( this->finish.thrd ); 248 } 249 else { 250 assert(this->finish.action_code == No_Action); 247 251 } 248 252 } … … 310 314 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 311 315 312 spin_lock( &lock );316 lock( &systemProcessor->cltr->lock ); 313 317 append( &systemProcessor->cltr->ready_queue, thrd ); 314 spin_unlock( &lock ); 318 unlock( &systemProcessor->cltr->lock ); 319 } 320 321 thread * nextThread(cluster * this) { 322 lock( &this->lock ); 323 thread * head = pop_head( &this->ready_queue ); 324 unlock( &this->lock ); 325 return head; 315 326 } 316 327 317 328 void ScheduleInternal() { 318 get_this_processor()->thread_action = Reschedule;319 329 suspend(); 320 330 } 321 331 322 thread * nextThread(cluster * this) { 323 spin_lock( &lock ); 324 thread * head = pop_head( &this->ready_queue ); 325 spin_unlock( &lock ); 326 return head; 332 void ScheduleInternal( spinlock * lock ) { 333 get_this_processor()->finish.action_code = Release; 334 get_this_processor()->finish.lock = lock; 335 suspend(); 336 } 337 338 void ScheduleInternal( thread * thrd ) { 339 get_this_processor()->finish.action_code = Schedule; 340 get_this_processor()->finish.thrd = thrd; 341 suspend(); 342 } 343 344 void ScheduleInternal( spinlock * lock, thread * thrd ) { 345 get_this_processor()->finish.action_code = Release_Schedule; 346 get_this_processor()->finish.lock = lock; 347 get_this_processor()->finish.thrd = thrd; 348 suspend(); 327 349 } 328 350 … … 374 396 // When its coroutine terminates, it return control to the mainThread 375 397 // which is currently here 376 systemProcessor-> terminated = true;398 systemProcessor->is_terminated = true; 377 399 suspend(); 378 400 … … 393 415 //----------------------------------------------------------------------------- 394 416 // Locks 395 void ?{}( simple_lock * this ) { 396 ( &this->blocked ){}; 397 } 398 399 void ^?{}( simple_lock * this ) { 400 401 } 402 403 void lock( simple_lock * this ) { 417 // void ?{}( simple_lock * this ) { 418 // ( &this->blocked ){}; 419 // } 420 421 // void ^?{}( simple_lock * this ) { 422 423 // } 424 425 // void lock( simple_lock * this ) { 426 // { 427 // spin_lock( &lock ); 428 // append( &this->blocked, this_thread() ); 429 // spin_unlock( &lock ); 430 // } 431 // ScheduleInternal(); 432 // } 433 434 // void lock( simple_lock * this, spinlock * to_release ) { 435 // { 436 // spin_lock( &lock ); 437 // append( &this->blocked, this_thread() ); 438 // spin_unlock( &lock ); 439 // } 440 // ScheduleInternal( to_release ); 441 // lock( to_release ); 442 // } 443 444 // void unlock( simple_lock * this ) { 445 // thread * it; 446 // while( it = pop_head( &this->blocked) ) { 447 // ScheduleThread( it ); 448 // } 449 // } 450 451 void ?{}( spinlock * this ) { 452 this->lock = 0; 453 } 454 void ^?{}( spinlock * this ) { 455 456 } 457 458 void lock( spinlock * this ) { 459 for ( unsigned int i = 1;; i += 1 ) { 460 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) break; 461 } 462 } 463 464 void unlock( spinlock * this ) { 465 __sync_lock_release_4( &this->lock ); 466 } 467 468 void ?{}( signal_once * this ) { 469 this->condition = false; 470 } 471 void ^?{}( signal_once * this ) { 472 473 } 474 475 void wait( signal_once * this ) { 476 lock( &this->lock ); 477 if( !this->condition ) { 478 append( &this->blocked, this_thread() ); 479 ScheduleInternal( &this->lock ); 480 lock( &this->lock ); 481 } 482 unlock( &this->lock ); 483 } 484 485 void signal( signal_once * this ) { 486 lock( &this->lock ); 404 487 { 405 spin_lock( &lock ); 406 append( &this->blocked, this_thread() ); 407 spin_unlock( &lock ); 408 } 409 suspend(); 410 } 411 412 void unlock( simple_lock * this ) { 413 thread * it; 414 while( it = pop_head( &this->blocked) ) { 415 ScheduleThread( it ); 416 } 488 this->condition = true; 489 490 thread * it; 491 while( it = pop_head( &this->blocked) ) { 492 ScheduleThread( it ); 493 } 494 } 495 unlock( &this->lock ); 417 496 } 418 497
Note: See TracChangeset
for help on using the changeset viewer.