- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/startup.cfa
r89eff25 r454f478 22 22 extern "C" { 23 23 #include <limits.h> // PTHREAD_STACK_MIN 24 #include <sys/eventfd.h> // eventfd25 24 #include <sys/mman.h> // mprotect 26 25 #include <sys/resource.h> // getrlimit … … 73 72 static void __kernel_first_resume( processor * this ); 74 73 static void __kernel_last_resume ( processor * this ); 75 static void init(processor & this, const char name[], cluster & _cltr , $thread * initT);74 static void init(processor & this, const char name[], cluster & _cltr); 76 75 static void deinit(processor & this); 77 76 static void doregister( struct cluster & cltr ); … … 90 89 extern void __kernel_alarm_startup(void); 91 90 extern void __kernel_alarm_shutdown(void); 91 extern void __kernel_io_startup (void); 92 extern void __kernel_io_shutdown(void); 92 93 93 94 //----------------------------------------------------------------------------- … … 101 102 KERNEL_STORAGE($thread, mainThread); 102 103 KERNEL_STORAGE(__stack_t, mainThreadCtx); 104 KERNEL_STORAGE(io_context, mainPollerThread); 103 105 KERNEL_STORAGE(__scheduler_RWLock_t, __scheduler_lock); 104 106 #if !defined(__CFA_NO_STATISTICS__) … … 196 198 197 199 void ?{}(processor & this) with( this ) { 200 ( this.idle ){}; 198 201 ( this.terminated ){}; 199 202 ( this.runner ){}; 200 init( this, "Main Processor", *mainCluster , 0p);203 init( this, "Main Processor", *mainCluster ); 201 204 kernel_thread = pthread_self(); 202 205 … … 223 226 __kernel_alarm_startup(); 224 227 228 // Start IO 229 __kernel_io_startup(); 230 225 231 // Add the main thread to the ready queue 226 232 // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread … … 235 241 // THE SYSTEM IS NOW COMPLETELY RUNNING 236 242 243 244 // SKULLDUGGERY: The constructor for the mainCluster will call alloc with a dimension of 0 245 // malloc *can* return a non-null value, we should free it if that is the case 246 free( mainCluster->io.ctxs ); 247 248 // Now that the system is up, finish creating systems that need threading 249 mainCluster->io.ctxs = (io_context *)&storage_mainPollerThread; 250 mainCluster->io.cnt = 1; 251 (*mainCluster->io.ctxs){ *mainCluster }; 252 237 253 __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n"); 238 254 … … 244 260 245 261 static void __kernel_shutdown(void) { 262 //Before we start shutting things down, wait for systems that need threading to shutdown 263 ^(*mainCluster->io.ctxs){}; 264 mainCluster->io.cnt = 0; 265 mainCluster->io.ctxs = 0p; 266 246 267 /* paranoid */ verify( __preemption_enabled() ); 247 268 disable_interrupts(); … … 262 283 __kernel_alarm_shutdown(); 263 284 264 #if !defined( __CFA_NO_STATISTICS__ ) 265 __stats_t * st = (__stats_t *)& storage_mainProcStats; 266 __tally_stats(mainCluster->stats, st); 267 if( 0 != mainProcessor->print_stats ) { 268 __print_stats( st, mainProcessor->print_stats, "Processor ", mainProcessor->name, (void*)mainProcessor ); 269 } 270 #if defined(CFA_STATS_ARRAY) 271 __flush_stat( st, "Processor", mainProcessor ); 272 #endif 273 #endif 285 // Stop IO 286 __kernel_io_shutdown(); 274 287 275 288 // Destroy the main processor and its context in reverse order of construction … … 351 364 __print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc ); 352 365 } 353 #if defined(CFA_STATS_ARRAY)354 __flush_stat( &local_stats, "Processor", proc );355 #endif356 366 #endif 357 367 … … 447 457 link.next = 0p; 448 458 link.prev = 0p; 449 link.preferred = -1u;450 last_proc = 0p;451 459 #if defined( __CFA_WITH_VERIFY__ ) 452 460 canary = 0x0D15EA5E0D15EA5Ep; … … 468 476 } 469 477 470 static void init(processor & this, const char name[], cluster & _cltr , $thread * initT) with( this ) {478 static void init(processor & this, const char name[], cluster & _cltr) with( this ) { 471 479 this.name = name; 472 480 this.cltr = &_cltr; 473 this.rdq.its = 0; 474 this.rdq.itr = 0; 475 this.rdq.id = -1u; 476 this.rdq.target = -1u; 477 this.rdq.cutoff = -1ull; 481 full_proc = true; 478 482 do_terminate = false; 479 483 preemption_alarm = 0p; 480 484 pending_preemption = false; 481 485 482 this.io.ctx = 0p;483 this.io.pending = false;484 this.io.dirty = false;485 486 this.init.thrd = initT;487 488 this.idle = eventfd(0, 0);489 if (idle < 0) {490 abort("KERNEL ERROR: PROCESSOR EVENTFD - %s\n", strerror(errno));491 }492 493 486 #if !defined(__CFA_NO_STATISTICS__) 494 487 print_stats = 0; … … 496 489 #endif 497 490 498 // Register and Lock the RWlock so no-one pushes/pops while we are changing the queue 499 uint_fast32_t last_size = ready_mutate_register((__processor_id_t*)&this); 500 this.cltr->procs.total += 1u; 501 insert_last(this.cltr->procs.actives, this); 491 lock( this.cltr->idles ); 492 int target = this.cltr->idles.total += 1u; 493 unlock( this.cltr->idles ); 494 495 id = doregister((__processor_id_t*)&this); 496 497 // Lock the RWlock so no-one pushes/pops while we are changing the queue 498 uint_fast32_t last_size = ready_mutate_lock(); 502 499 503 500 // Adjust the ready queue size 504 ready_queue_grow( cltr );501 ready_queue_grow( cltr, target ); 505 502 506 503 // Unlock the RWlock … … 512 509 // Not a ctor, it just preps the destruction but should not destroy members 513 510 static void deinit(processor & this) { 511 lock( this.cltr->idles ); 512 int target = this.cltr->idles.total -= 1u; 513 unlock( this.cltr->idles ); 514 514 515 // Lock the RWlock so no-one pushes/pops while we are changing the queue 515 516 uint_fast32_t last_size = ready_mutate_lock(); 516 this.cltr->procs.total -= 1u;517 remove(this);518 517 519 518 // Adjust the ready queue size 520 ready_queue_shrink( this.cltr ); 521 522 // Unlock the RWlock and unregister: we don't need the read_lock any more 523 ready_mutate_unregister((__processor_id_t*)&this, last_size ); 524 525 close(this.idle); 526 } 527 528 void ?{}(processor & this, const char name[], cluster & _cltr, $thread * initT) { 519 ready_queue_shrink( this.cltr, target ); 520 521 // Unlock the RWlock 522 ready_mutate_unlock( last_size ); 523 524 // Finally we don't need the read_lock any more 525 unregister((__processor_id_t*)&this); 526 } 527 528 void ?{}(processor & this, const char name[], cluster & _cltr) { 529 ( this.idle ){}; 529 530 ( this.terminated ){}; 530 531 ( this.runner ){}; 531 532 532 533 disable_interrupts(); 533 init( this, name, _cltr , initT);534 init( this, name, _cltr ); 534 535 enable_interrupts( __cfaabi_dbg_ctx ); 535 536 … … 537 538 538 539 this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this ); 539 } 540 541 void ?{}(processor & this, const char name[], cluster & _cltr) { 542 (this){name, _cltr, 0p}; 540 543 541 } 544 542 … … 564 562 //----------------------------------------------------------------------------- 565 563 // Cluster 566 static void ?{}(__cluster_ proc_list& this) {564 static void ?{}(__cluster_idles & this) { 567 565 this.lock = 0; 568 566 this.idle = 0; 569 567 this.total = 0; 568 (this.list){}; 570 569 } 571 570 … … 583 582 threads{ __get }; 584 583 585 io.arbiter = create();586 io.params = io_params;587 588 584 doregister(this); 589 585 … … 593 589 594 590 // Adjust the ready queue size 595 ready_queue_grow( &this );591 ready_queue_grow( &this, 0 ); 596 592 597 593 // Unlock the RWlock 598 594 ready_mutate_unlock( last_size ); 599 595 enable_interrupts_noPoll(); // Don't poll, could be in main cluster 596 597 598 this.io.cnt = num_io; 599 this.io.ctxs = aalloc(num_io); 600 for(i; this.io.cnt) { 601 (this.io.ctxs[i]){ this, io_params }; 602 } 600 603 } 601 604 602 605 void ^?{}(cluster & this) { 603 destroy(this.io.arbiter); 606 for(i; this.io.cnt) { 607 ^(this.io.ctxs[i]){ true }; 608 } 609 free(this.io.ctxs); 604 610 605 611 // Lock the RWlock so no-one pushes/pops while we are changing the queue … … 608 614 609 615 // Adjust the ready queue size 610 ready_queue_shrink( &this );616 ready_queue_shrink( &this, 0 ); 611 617 612 618 // Unlock the RWlock … … 618 624 __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this ); 619 625 } 620 #if defined(CFA_STATS_ARRAY)621 __flush_stat( this.stats, "Cluster", &this );622 #endif623 626 free( this.stats ); 624 627 #endif … … 733 736 } 734 737 738 735 739 #if defined(__CFA_WITH_VERIFY__) 736 740 static bool verify_fwd_bck_rng(void) {
Note:
See TracChangeset
for help on using the changeset viewer.