- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.cfa (modified) (28 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
rf586539 r8e16177 15 15 16 16 #define __cforall_thread__ 17 // #define __CFA_DEBUG_PRINT_RUNTIME_CORE__ 17 18 18 19 //C Includes … … 40 41 #include "invoke.h" 41 42 43 42 44 //----------------------------------------------------------------------------- 43 45 // Some assembly required … … 230 232 idle{}; 231 233 232 __cfa abi_dbg_print_safe("Kernel : Starting core %p\n", &this);234 __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this); 233 235 234 236 this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this ); 235 237 236 __cfa abi_dbg_print_safe("Kernel : core %p started\n", &this);238 __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this); 237 239 } 238 240 239 241 void ^?{}(processor & this) with( this ){ 240 242 if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) { 241 __cfa abi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);243 __cfadbg_print_safe(runtime_core, "Kernel : core %p signaling termination\n", &this); 242 244 243 245 __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED); … … 248 250 } 249 251 250 pthread_join( kernel_thread, 0p ); 252 int err = pthread_join( kernel_thread, 0p ); 253 if( err != 0 ) abort("KERNEL ERROR: joining processor %p caused error %s\n", &this, strerror(err)); 254 251 255 free( this.stack ); 252 256 } 253 257 254 void ?{}(cluster & this, const char name[], Duration preemption_rate ) with( this ) {258 void ?{}(cluster & this, const char name[], Duration preemption_rate, int io_flags) with( this ) { 255 259 this.name = name; 256 260 this.preemption_rate = preemption_rate; … … 258 262 ready_queue_lock{}; 259 263 264 #if !defined(__CFA_NO_STATISTICS__) 265 print_stats = false; 266 #endif 267 260 268 procs{ __get }; 261 269 idles{ __get }; 262 270 threads{ __get }; 263 271 272 __kernel_io_startup( this, io_flags, &this == mainCluster ); 273 264 274 doregister(this); 265 275 } 266 276 267 277 void ^?{}(cluster & this) { 278 __kernel_io_shutdown( this, &this == mainCluster ); 279 268 280 unregister(this); 269 281 } … … 281 293 verify(this); 282 294 283 __cfa abi_dbg_print_safe("Kernel : core %p starting\n", this);295 __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this); 284 296 285 297 doregister(this->cltr, this); … … 289 301 preemption_scope scope = { this }; 290 302 291 __cfa abi_dbg_print_safe("Kernel : core %p started\n", this);303 __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this); 292 304 293 305 $thread * readyThread = 0p; … … 315 327 } 316 328 317 __cfa abi_dbg_print_safe("Kernel : core %p stopping\n", this);329 __cfadbg_print_safe(runtime_core, "Kernel : core %p stopping\n", this); 318 330 } 319 331 … … 322 334 V( this->terminated ); 323 335 324 __cfa abi_dbg_print_safe("Kernel : core %p terminated\n", this);336 __cfadbg_print_safe(runtime_core, "Kernel : core %p terminated\n", this); 325 337 326 338 // HACK : the coroutine context switch expects this_thread to be set … … 467 479 468 480 //We now have a proper context from which to schedule threads 469 __cfa abi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx);481 __cfadbg_print_safe(runtime_core, "Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx); 470 482 471 483 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't … … 478 490 479 491 // Main routine of the core returned, the core is now fully terminated 480 __cfa abi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, &proc->runner);492 __cfadbg_print_safe(runtime_core, "Kernel : core %p main ended (%p)\n", proc, &proc->runner); 481 493 482 494 return 0p; … … 611 623 } 612 624 613 void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) { 614 if( !thrd ) return; 615 616 disable_interrupts(); 625 // KERNEL ONLY unpark with out disabling interrupts 626 void __unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) { 617 627 static_assert(sizeof(thrd->state) == sizeof(int)); 618 628 … … 643 653 abort(); 644 654 } 655 } 656 657 void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) { 658 if( !thrd ) return; 659 660 disable_interrupts(); 661 __unpark( thrd __cfaabi_dbg_ctx_fwd2 ); 645 662 enable_interrupts( __cfaabi_dbg_ctx ); 646 663 } … … 704 721 static void __kernel_startup(void) { 705 722 verify( ! kernelTLS.preemption_state.enabled ); 706 __cfa abi_dbg_print_safe("Kernel : Starting\n");723 __cfadbg_print_safe(runtime_core, "Kernel : Starting\n"); 707 724 708 725 __page_size = sysconf( _SC_PAGESIZE ); … … 715 732 (*mainCluster){"Main Cluster"}; 716 733 717 __cfa abi_dbg_print_safe("Kernel : Main cluster ready\n");734 __cfadbg_print_safe(runtime_core, "Kernel : Main cluster ready\n"); 718 735 719 736 // Start by initializing the main thread … … 725 742 (*mainThread){ &info }; 726 743 727 __cfa abi_dbg_print_safe("Kernel : Main thread ready\n");744 __cfadbg_print_safe(runtime_core, "Kernel : Main thread ready\n"); 728 745 729 746 … … 746 763 747 764 runner{ &this }; 748 __cfa abi_dbg_print_safe("Kernel : constructed main processor context %p\n", &runner);765 __cfadbg_print_safe(runtime_core, "Kernel : constructed main processor context %p\n", &runner); 749 766 } 750 767 … … 771 788 772 789 773 774 790 // THE SYSTEM IS NOW COMPLETELY RUNNING 775 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 791 792 793 // Now that the system is up, finish creating systems that need threading 794 __kernel_io_finish_start( *mainCluster ); 795 796 797 __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n"); 776 798 777 799 verify( ! kernelTLS.preemption_state.enabled ); … … 781 803 782 804 static void __kernel_shutdown(void) { 783 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 805 //Before we start shutting things down, wait for systems that need threading to shutdown 806 __kernel_io_prepare_stop( *mainCluster ); 784 807 785 808 /* paranoid */ verify( TL_GET( preemption_state.enabled ) ); 786 809 disable_interrupts(); 787 810 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 811 812 __cfadbg_print_safe(runtime_core, "\n--------------------------------------------------\nKernel : Shutting down\n"); 788 813 789 814 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 801 826 // Destroy the main processor and its context in reverse order of construction 802 827 // These were manually constructed so we need manually destroy them 828 void ^?{}(processor & this) with( this ){ 829 /* paranoid */ verify( this.do_terminate == true ); 830 } 831 803 832 ^(*mainProcessor){}; 804 833 … … 808 837 ^(*mainThread){}; 809 838 839 ^(*mainCluster){}; 840 810 841 ^(__cfa_dbg_global_clusters.list){}; 811 842 ^(__cfa_dbg_global_clusters.lock){}; 812 843 813 __cfa abi_dbg_print_safe("Kernel : Shutdown complete\n");844 __cfadbg_print_safe(runtime_core, "Kernel : Shutdown complete\n"); 814 845 } 815 846 … … 836 867 837 868 // We are ready to sleep 838 __cfa abi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);869 __cfadbg_print_safe(runtime_core, "Kernel : Processor %p ready to sleep\n", this); 839 870 wait( idle ); 840 871 841 872 // We have woken up 842 __cfa abi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);873 __cfadbg_print_safe(runtime_core, "Kernel : Processor %p woke up and ready to run\n", this); 843 874 844 875 // Get ourself off the idle list … … 856 887 static bool __wake_one(cluster * this, __attribute__((unused)) bool force) { 857 888 // if we don't want to force check if we know it's false 858 if( !this->idles.head && !force ) return false;889 // if( !this->idles.head && !force ) return false; 859 890 860 891 // First, lock the cluster idle … … 869 900 870 901 // Wake them up 902 __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this->idles.head); 903 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 871 904 post( this->idles.head->idle ); 872 905 … … 878 911 // Unconditionnaly wake a thread 879 912 static bool __wake_proc(processor * this) { 880 return post( this->idle ); 913 __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this); 914 915 disable_interrupts(); 916 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 917 bool ret = post( this->idle ); 918 enable_interrupts( __cfaabi_dbg_ctx ); 919 920 return ret; 881 921 } 882 922 … … 960 1000 void ^?{}(semaphore & this) {} 961 1001 962 voidP(semaphore & this) with( this ){1002 bool P(semaphore & this) with( this ){ 963 1003 lock( lock __cfaabi_dbg_ctx2 ); 964 1004 count -= 1; … … 970 1010 unlock( lock ); 971 1011 park( __cfaabi_dbg_ctx ); 1012 return true; 972 1013 } 973 1014 else { 974 1015 unlock( lock ); 1016 return false; 975 1017 } 976 1018 } … … 989 1031 // make new owner 990 1032 unpark( thrd __cfaabi_dbg_ctx2 ); 1033 1034 return thrd != 0p; 1035 } 1036 1037 bool V(semaphore & this, unsigned diff) with( this ) { 1038 $thread * thrd = 0p; 1039 lock( lock __cfaabi_dbg_ctx2 ); 1040 int release = max(-count, (int)diff); 1041 count += diff; 1042 for(release) { 1043 unpark( pop_head( waiting ) __cfaabi_dbg_ctx2 ); 1044 } 1045 1046 unlock( lock ); 991 1047 992 1048 return thrd != 0p;
Note:
See TracChangeset
for help on using the changeset viewer.