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