Changeset 9236060 for src/libcfa/concurrency
- Timestamp:
- Aug 14, 2017, 2:03:39 PM (8 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:
- 74b007ba
- Parents:
- fd344aa (diff), 54cd58b0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/libcfa/concurrency
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/CtxSwitch-i386.S
rfd344aa r9236060 1 // -*- Mode: Asm -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Dec 6 12:27:26 2016 12 // Last Modified By : Thierry Delisle13 // Last Modified On : Tue Dec 6 12:27:26 201614 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:29:25 2017 13 // Update Count : 1 15 14 // 16 15 // This library is free software; you can redistribute it and/or modify it … … 99 98 100 99 // Local Variables: // 101 // compile-command: "make install" // 100 // mode: c // 101 // tab-width: 4 // 102 102 // End: // -
src/libcfa/concurrency/CtxSwitch-x86_64.S
rfd344aa r9236060 1 // -*- Mode: Asm -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Mon Nov 28 12:27:26 2016 12 // Last Modified By : Thierry Delisle13 // Last Modified On : Mon Nov 28 12:27:26 201614 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:28:11 2017 13 // Update Count : 1 15 14 // 16 15 // This library is free software; you can redistribute it and/or modify it -
src/libcfa/concurrency/alarm.c
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Fri Jun 2 11:31:25 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:35:18 2017 13 // Update Count : 1 15 14 // 16 15 … … 31 30 32 31 //============================================================================================= 32 // time type 33 //============================================================================================= 34 35 #define one_second 1_000_000_000ul 36 #define one_milisecond 1_000_000ul 37 #define one_microsecond 1_000ul 38 #define one_nanosecond 1ul 39 40 __cfa_time_t zero_time = { 0 }; 41 42 void ?{}( __cfa_time_t & this ) { this.val = 0; } 43 void ?{}( __cfa_time_t & this, zero_t zero ) { this.val = 0; } 44 45 void ?{}( itimerval & this, __cfa_time_t * alarm ) { 46 this.it_value.tv_sec = alarm->val / one_second; // seconds 47 this.it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds 48 this.it_interval.tv_sec = 0; 49 this.it_interval.tv_usec = 0; 50 } 51 52 53 void ?{}( __cfa_time_t & this, timespec * curr ) { 54 uint64_t secs = curr->tv_sec; 55 uint64_t nsecs = curr->tv_nsec; 56 this.val = (secs * one_second) + nsecs; 57 } 58 59 __cfa_time_t ?=?( __cfa_time_t & this, zero_t rhs ) { 60 this.val = 0; 61 return this; 62 } 63 64 __cfa_time_t from_s ( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000_000ul; return ret; } 65 __cfa_time_t from_ms( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000ul; return ret; } 66 __cfa_time_t from_us( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000ul; return ret; } 67 __cfa_time_t from_ns( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1ul; return ret; } 68 69 //============================================================================================= 33 70 // Clock logic 34 71 //============================================================================================= … … 37 74 timespec curr; 38 75 clock_gettime( CLOCK_REALTIME, &curr ); 39 __cfa_time_t curr_time = ((__cfa_time_t)curr.tv_sec * TIMEGRAN) + curr.tv_nsec; 40 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : current time is %lu\n", curr_time ); 41 return curr_time; 76 return (__cfa_time_t){ &curr }; 42 77 } 43 78 44 79 void __kernel_set_timer( __cfa_time_t alarm ) { 45 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : set timer to %lu\n", (__cfa_time_t)alarm ); 46 itimerval val; 47 val.it_value.tv_sec = alarm / TIMEGRAN; // seconds 48 val.it_value.tv_usec = (alarm % TIMEGRAN) / ( TIMEGRAN / 1_000_000L ); // microseconds 49 val.it_interval.tv_sec = 0; 50 val.it_interval.tv_usec = 0; 80 itimerval val = { &alarm }; 51 81 setitimer( ITIMER_REAL, &val, NULL ); 52 82 } … … 56 86 //============================================================================================= 57 87 58 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0) {88 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 59 89 this.thrd = thrd; 60 90 this.alarm = alarm; … … 65 95 } 66 96 67 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0) {97 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 68 98 this.proc = proc; 69 99 this.alarm = alarm; … … 153 183 154 184 void register_self( alarm_node_t * this ) { 185 alarm_list_t * alarms = &event_kernel->alarms; 186 155 187 disable_interrupts(); 156 verify( !systemProcessor->pending_alarm ); 157 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 188 lock( &event_kernel->lock DEBUG_CTX2 ); 158 189 { 159 verify( validate( &systemProcessor->alarms ) );160 bool first = ! systemProcessor->alarms.head;161 162 insert( &systemProcessor->alarms, this );163 if( systemProcessor->pending_alarm) {164 tick_preemption();190 verify( validate( alarms ) ); 191 bool first = !alarms->head; 192 193 insert( alarms, this ); 194 if( first ) { 195 __kernel_set_timer( alarms->head->alarm - __kernel_get_time() ); 165 196 } 166 if( first ) { 167 __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() ); 168 } 169 } 170 unlock( &systemProcessor->alarm_lock ); 197 } 198 unlock( &event_kernel->lock ); 171 199 this->set = true; 172 200 enable_interrupts( DEBUG_CTX ); … … 174 202 175 203 void unregister_self( alarm_node_t * this ) { 176 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );177 204 disable_interrupts(); 178 lock( & systemProcessor->alarm_lock DEBUG_CTX2 );205 lock( &event_kernel->lock DEBUG_CTX2 ); 179 206 { 180 verify( validate( & systemProcessor->alarms ) );181 remove( & systemProcessor->alarms, this );182 } 183 unlock( & systemProcessor->alarm_lock );207 verify( validate( &event_kernel->alarms ) ); 208 remove( &event_kernel->alarms, this ); 209 } 210 unlock( &event_kernel->lock ); 184 211 enable_interrupts( DEBUG_CTX ); 185 212 this->set = false; 186 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this ); 187 } 213 } 214 215 // Local Variables: // 216 // mode: c // 217 // tab-width: 4 // 218 // End: // -
src/libcfa/concurrency/alarm.h
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Fri Jun 2 11:31:25 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:59:27 2017 13 // Update Count : 3 15 14 // 16 15 17 #ifndef ALARM_H 18 #define ALARM_H 16 #pragma once 19 17 20 18 #include <stdbool.h> 19 #include <stdint.h> 21 20 22 #include "assert" 23 24 typedef unsigned long int __cfa_time_t; 21 #include <assert.h> 25 22 26 23 struct thread_desc; 27 24 struct processor; 28 25 26 struct timespec; 27 struct itimerval; 28 29 //============================================================================================= 30 // time type 31 //============================================================================================= 32 33 struct __cfa_time_t { 34 uint64_t val; 35 }; 36 37 // ctors 38 void ?{}( __cfa_time_t & this ); 39 void ?{}( __cfa_time_t & this, zero_t zero ); 40 void ?{}( __cfa_time_t & this, timespec * curr ); 41 void ?{}( itimerval & this, __cfa_time_t * alarm ); 42 43 __cfa_time_t ?=?( __cfa_time_t & this, zero_t rhs ); 44 45 // logical ops 46 static inline bool ?==?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val == rhs.val; } 47 static inline bool ?!=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val != rhs.val; } 48 static inline bool ?>? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val > rhs.val; } 49 static inline bool ?<? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val < rhs.val; } 50 static inline bool ?>=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >= rhs.val; } 51 static inline bool ?<=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <= rhs.val; } 52 53 static inline bool ?==?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val == rhs; } 54 static inline bool ?!=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val != rhs; } 55 static inline bool ?>? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val > rhs; } 56 static inline bool ?<? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val < rhs; } 57 static inline bool ?>=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >= rhs; } 58 static inline bool ?<=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <= rhs; } 59 60 // addition/substract 61 static inline __cfa_time_t ?+?( __cfa_time_t lhs, __cfa_time_t rhs ) { 62 __cfa_time_t ret; 63 ret.val = lhs.val + rhs.val; 64 return ret; 65 } 66 67 static inline __cfa_time_t ?-?( __cfa_time_t lhs, __cfa_time_t rhs ) { 68 __cfa_time_t ret; 69 ret.val = lhs.val - rhs.val; 70 return ret; 71 } 72 73 __cfa_time_t from_s ( uint64_t ); 74 __cfa_time_t from_ms( uint64_t ); 75 __cfa_time_t from_us( uint64_t ); 76 __cfa_time_t from_ns( uint64_t ); 77 78 extern __cfa_time_t zero_time; 79 29 80 //============================================================================================= 30 81 // Clock logic 31 82 //============================================================================================= 32 33 #define TIMEGRAN 1_000_000_000L // nanosecond granularity, except for timeval34 83 35 84 __cfa_time_t __kernel_get_time(); … … 56 105 typedef alarm_node_t ** __alarm_it_t; 57 106 58 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0, __cfa_time_t period = 0);59 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = 0, __cfa_time_t period = 0);107 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ); 108 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ); 60 109 void ^?{}( alarm_node_t & this ); 61 110 … … 76 125 void unregister_self( alarm_node_t * this ); 77 126 78 #endif79 80 127 // Local Variables: // 81 // mode: CFA//128 // mode: c // 82 129 // tab-width: 6 // 83 130 // End: // -
src/libcfa/concurrency/coroutine
rfd344aa r9236060 10 10 // Author : Thierry Delisle 11 11 // Created On : Mon Nov 28 12:27:26 2016 12 // Last Modified By : Thierry Delisle13 // Last Modified On : Mon Nov 28 12:27:26 201614 // Update Count : 012 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Sat Jul 22 09:57:17 2017 14 // Update Count : 2 15 15 // 16 16 17 #ifndef COROUTINES_H 18 #define COROUTINES_H 17 #pragma once 19 18 20 #include "assert"19 #include <assert.h> 21 20 #include "invoke.h" 22 21 … … 63 62 64 63 // Get current coroutine 65 extern volatile thread_local coroutine_desc *this_coroutine;64 extern thread_local coroutine_desc * volatile this_coroutine; 66 65 67 66 // Private wrappers for context switch and stack creation … … 129 128 } 130 129 131 #endif //COROUTINES_H132 133 130 // Local Variables: // 134 131 // mode: c // -
src/libcfa/concurrency/coroutine.c
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Mon Nov 28 12:27:26 2016 12 // Last Modified By : Thierry Delisle13 // Last Modified On : Mon Nov 28 12:27:26 201614 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:34:57 2017 13 // Update Count : 1 15 14 // 16 15 … … 26 25 } 27 26 28 #include "kernel" 29 #include "libhdr.h" 27 #include "kernel_private.h" 30 28 31 29 #define __CFA_INVOKE_PRIVATE__ 32 30 #include "invoke.h" 33 31 34 extern volatile thread_local processor * this_processor;35 32 36 33 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/invoke.c
rfd344aa r9236060 1 // -*- Mode: C -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2016 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:28:33 2017 13 // Update Count : 1 15 14 // 16 15 … … 142 141 #endif 143 142 } 143 144 // Local Variables: // 145 // mode: c // 146 // tab-width: 4 // 147 // End: // -
src/libcfa/concurrency/invoke.h
rfd344aa r9236060 1 // -*- Mode: C -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2016 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:28:56 2017 13 // Update Count : 1 15 14 // 16 15 … … 130 129 } 131 130 #endif 131 132 // Local Variables: // 133 // mode: c // 134 // tab-width: 4 // 135 // End: // -
src/libcfa/concurrency/kernel
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:58:39 2017 13 // Update Count : 2 15 14 // 16 15 17 #ifndef KERNEL_H 18 #define KERNEL_H 16 #pragma once 19 17 20 18 #include <stdbool.h> … … 28 26 //----------------------------------------------------------------------------- 29 27 // Locks 30 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 31 void lock ( spinlock * DEBUG_CTX_PARAM2 );32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 void unlock ( spinlock * ); 28 void lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, spin if already acquired 29 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, yield repeatedly if already acquired 30 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, return false if already acquired 31 void unlock ( spinlock * ); // Unlock the spinlock 34 32 35 33 struct semaphore { … … 48 46 // Cluster 49 47 struct cluster { 50 __thread_queue_t ready_queue; 51 spinlock lock; 48 spinlock ready_queue_lock; // Ready queue locks 49 __thread_queue_t ready_queue; // Ready queue for threads 50 unsigned long long int preemption; // Preemption rate on this cluster 52 51 }; 53 52 … … 76 75 static inline void ^?{}(FinishAction & this) {} 77 76 77 // Processor 78 // Wrapper around kernel threads 78 79 struct processor { 79 struct processorCtx_t * runner; 80 cluster * cltr; 81 pthread_t kernel_thread; 80 // Main state 81 struct processorCtx_t * runner; // Coroutine ctx who does keeps the state of the processor 82 cluster * cltr; // Cluster from which to get threads 83 pthread_t kernel_thread; // Handle to pthreads 82 84 83 semaphore terminated; 84 volatile bool is_terminated; 85 // Termination 86 volatile bool do_terminate; // Set to true to notify the processor should terminate 87 semaphore terminated; // Termination synchronisation 85 88 86 struct FinishAction finish; 89 // RunThread data 90 struct FinishAction finish; // Action to do after a thread is ran 87 91 88 struct alarm_node_t * preemption_alarm; 89 unsigned int preemption; 92 // Preemption data 93 struct alarm_node_t * preemption_alarm; // Node which is added in the discrete event simulaiton 94 bool pending_preemption; // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible 90 95 91 bool pending_preemption; 92 93 char * last_enable; 96 #ifdef __CFA_DEBUG__ 97 char * last_enable; // Last function to enable preemption on this processor 98 #endif 94 99 }; 95 100 … … 98 103 void ^?{}(processor & this); 99 104 100 #endif //KERNEL_H101 102 105 // Local Variables: // 103 // mode: CFA//104 // tab-width: 6//106 // mode: c // 107 // tab-width: 4 // 105 108 // End: // -
src/libcfa/concurrency/kernel.c
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:33:18 2017 13 // Update Count : 2 15 14 // 16 15 … … 42 41 //----------------------------------------------------------------------------- 43 42 // Kernel storage 44 #define KERNEL_STORAGE(T,X) static char X##Storage[sizeof(T)] 45 46 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx); 47 KERNEL_STORAGE(cluster, systemCluster); 48 KERNEL_STORAGE(system_proc_t, systemProcessor); 49 KERNEL_STORAGE(thread_desc, mainThread); 43 KERNEL_STORAGE(cluster, mainCluster); 44 KERNEL_STORAGE(processor, mainProcessor); 45 KERNEL_STORAGE(processorCtx_t, mainProcessorCtx); 46 KERNEL_STORAGE(thread_desc, mainThread); 50 47 KERNEL_STORAGE(machine_context_t, mainThreadCtx); 51 48 52 cluster * systemCluster;53 system_proc_t * systemProcessor;49 cluster * mainCluster; 50 processor * mainProcessor; 54 51 thread_desc * mainThread; 55 52 … … 57 54 // Global state 58 55 59 volatile thread_local processor * this_processor; 60 volatile thread_local coroutine_desc * this_coroutine; 61 volatile thread_local thread_desc * this_thread; 56 thread_local coroutine_desc * volatile this_coroutine; 57 thread_local thread_desc * volatile this_thread; 58 thread_local processor * volatile this_processor; 59 62 60 volatile thread_local bool preemption_in_progress = 0; 63 61 volatile thread_local unsigned short disable_preempt_count = 1; … … 85 83 86 84 this.limit = (void *)(((intptr_t)this.base) - this.size); 87 this.context = & mainThreadCtxStorage;85 this.context = &storage_mainThreadCtx; 88 86 this.top = this.base; 89 87 } … … 125 123 126 124 void ?{}(processor & this) { 127 this{ systemCluster };125 this{ mainCluster }; 128 126 } 129 127 … … 131 129 this.cltr = cltr; 132 130 (this.terminated){ 0 }; 133 this. is_terminated= false;131 this.do_terminate = false; 134 132 this.preemption_alarm = NULL; 135 this.preemption = default_preemption();136 133 this.pending_preemption = false; 137 134 … … 142 139 this.cltr = cltr; 143 140 (this.terminated){ 0 }; 144 this. is_terminated= false;141 this.do_terminate = false; 145 142 this.preemption_alarm = NULL; 146 this.preemption = default_preemption();147 143 this.pending_preemption = false; 148 144 this.kernel_thread = pthread_self(); 149 145 150 146 this.runner = &runner; 151 LIB_DEBUG_PRINT_SAFE("Kernel : constructing systemprocessor context %p\n", &runner);147 LIB_DEBUG_PRINT_SAFE("Kernel : constructing main processor context %p\n", &runner); 152 148 runner{ &this }; 153 149 } 154 150 155 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )156 157 void ?{}(system_proc_t & this, cluster * cltr, processorCtx_t & runner) {158 (this.alarms){};159 (this.alarm_lock){};160 this.pending_alarm = false;161 162 (this.proc){ cltr, runner };163 164 verify( validate( &this.alarms ) );165 }166 167 151 void ^?{}(processor & this) { 168 if( ! this. is_terminated) {152 if( ! this.do_terminate ) { 169 153 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", &this); 170 this. is_terminated= true;154 this.do_terminate = true; 171 155 P( &this.terminated ); 172 156 pthread_join( this.kernel_thread, NULL ); … … 176 160 void ?{}(cluster & this) { 177 161 ( this.ready_queue ){}; 178 ( this.lock ){}; 162 ( this.ready_queue_lock ){}; 163 164 this.preemption = default_preemption(); 179 165 } 180 166 … … 199 185 200 186 thread_desc * readyThread = NULL; 201 for( unsigned int spin_count = 0; ! this-> is_terminated; spin_count++ )187 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ ) 202 188 { 203 189 readyThread = nextThread( this->cltr ); … … 343 329 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 344 330 345 lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );346 append( & systemProcessor->proc.cltr->ready_queue, thrd );347 unlock( & systemProcessor->proc.cltr->lock );331 lock( &this_processor->cltr->ready_queue_lock DEBUG_CTX2 ); 332 append( &this_processor->cltr->ready_queue, thrd ); 333 unlock( &this_processor->cltr->ready_queue_lock ); 348 334 349 335 verify( disable_preempt_count > 0 ); … … 352 338 thread_desc * nextThread(cluster * this) { 353 339 verify( disable_preempt_count > 0 ); 354 lock( &this-> lock DEBUG_CTX2 );340 lock( &this->ready_queue_lock DEBUG_CTX2 ); 355 341 thread_desc * head = pop_head( &this->ready_queue ); 356 unlock( &this-> lock );342 unlock( &this->ready_queue_lock ); 357 343 verify( disable_preempt_count > 0 ); 358 344 return head; … … 452 438 // Start by initializing the main thread 453 439 // SKULLDUGGERY: the mainThread steals the process main thread 454 // which will then be scheduled by the systemProcessor normally455 mainThread = (thread_desc *)& mainThreadStorage;440 // which will then be scheduled by the mainProcessor normally 441 mainThread = (thread_desc *)&storage_mainThread; 456 442 current_stack_info_t info; 457 443 (*mainThread){ &info }; … … 459 445 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 460 446 461 // Initialize the systemcluster462 systemCluster = (cluster *)&systemClusterStorage;463 (* systemCluster){};464 465 LIB_DEBUG_PRINT_SAFE("Kernel : Systemcluster ready\n");466 467 // Initialize the system processor and the systemprocessor ctx447 // Initialize the main cluster 448 mainCluster = (cluster *)&storage_mainCluster; 449 (*mainCluster){}; 450 451 LIB_DEBUG_PRINT_SAFE("Kernel : main cluster ready\n"); 452 453 // Initialize the main processor and the main processor ctx 468 454 // (the coroutine that contains the processing control flow) 469 systemProcessor = (system_proc_t *)&systemProcessorStorage; 470 (*systemProcessor){ systemCluster, *(processorCtx_t *)&systemProcessorCtxStorage }; 471 472 // Add the main thread to the ready queue 473 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread 474 ScheduleThread(mainThread); 455 mainProcessor = (processor *)&storage_mainProcessor; 456 (*mainProcessor){ mainCluster, *(processorCtx_t *)&storage_mainProcessorCtx }; 475 457 476 458 //initialize the global state variables 477 this_processor = &systemProcessor->proc;459 this_processor = mainProcessor; 478 460 this_thread = mainThread; 479 461 this_coroutine = &mainThread->cor; 480 disable_preempt_count = 1;481 462 482 463 // Enable preemption 483 464 kernel_start_preemption(); 484 465 485 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 466 // Add the main thread to the ready queue 467 // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread 468 ScheduleThread(mainThread); 469 470 // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX 486 471 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 487 472 // mainThread is on the ready queue when this call is made. 488 resume( * systemProcessor->proc.runner );473 resume( *mainProcessor->runner ); 489 474 490 475 … … 501 486 disable_interrupts(); 502 487 503 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.488 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. 504 489 // When its coroutine terminates, it return control to the mainThread 505 490 // which is currently here 506 systemProcessor->proc.is_terminated= true;491 mainProcessor->do_terminate = true; 507 492 suspend(); 508 493 … … 512 497 kernel_stop_preemption(); 513 498 514 // Destroy the systemprocessor and its context in reverse order of construction499 // Destroy the main processor and its context in reverse order of construction 515 500 // These were manually constructed so we need manually destroy them 516 ^(* systemProcessor->proc.runner){};517 ^( systemProcessor){};501 ^(*mainProcessor->runner){}; 502 ^(mainProcessor){}; 518 503 519 504 // Final step, destroy the main thread since it is no longer needed … … 699 684 return top; 700 685 } 686 701 687 // Local Variables: // 702 688 // mode: c // -
src/libcfa/concurrency/kernel_private.h
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Mon Feb 13 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:58:09 2017 13 // Update Count : 2 15 14 // 16 15 17 #ifndef KERNEL_PRIVATE_H 18 #define KERNEL_PRIVATE_H 16 #pragma once 19 17 20 18 #include "libhdr.h" … … 31 29 extern "C" { 32 30 void disable_interrupts(); 33 void enable_interrupts_no RF();31 void enable_interrupts_noPoll(); 34 32 void enable_interrupts( DEBUG_CTX_PARAM ); 35 33 } … … 45 43 thread_desc * nextThread(cluster * this); 46 44 45 //Block current thread and release/wake-up the following resources 47 46 void BlockInternal(void); 48 47 void BlockInternal(spinlock * lock); … … 65 64 void spin(processor * this, unsigned int * spin_count); 66 65 67 struct system_proc_t { 68 processor proc; 69 66 struct event_kernel_t { 70 67 alarm_list_t alarms; 71 spinlock alarm_lock; 72 73 bool pending_alarm; 68 spinlock lock; 74 69 }; 75 70 76 extern cluster * systemCluster; 77 extern system_proc_t * systemProcessor; 78 extern volatile thread_local processor * this_processor; 79 extern volatile thread_local coroutine_desc * this_coroutine; 80 extern volatile thread_local thread_desc * this_thread; 71 extern event_kernel_t * event_kernel; 72 73 extern thread_local coroutine_desc * volatile this_coroutine; 74 extern thread_local thread_desc * volatile this_thread; 75 extern thread_local processor * volatile this_processor; 76 81 77 extern volatile thread_local bool preemption_in_progress; 82 78 extern volatile thread_local unsigned short disable_preempt_count; … … 91 87 extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 92 88 93 #endif //KERNEL_PRIVATE_H 89 //----------------------------------------------------------------------------- 90 // Utils 91 #define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)] 94 92 95 93 // Local Variables: // -
src/libcfa/concurrency/monitor
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Thd Feb 23 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:59:01 2017 13 // Update Count : 3 15 14 // 16 15 17 #ifndef MONITOR_H 18 #define MONITOR_H 16 #pragma once 19 17 20 18 #include <stddef.h> 21 19 22 #include "assert"20 #include <assert.h> 23 21 #include "invoke.h" 24 22 #include "stdlib" … … 99 97 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ); 100 98 101 #endif //MONITOR_H 99 // Local Variables: // 100 // mode: c // 101 // tab-width: 4 // 102 // End: // -
src/libcfa/concurrency/monitor.c
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Thd Feb 23 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jul 31 14:59:05 2017 13 // Update Count : 3 15 14 // 16 15 … … 485 484 if( !this->monitors ) { 486 485 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 487 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition ", thrd->current_monitors );486 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition %p", thrd->current_monitors ); 488 487 this->monitor_count = thrd->current_monitor_count; 489 488 … … 528 527 return head; 529 528 } 529 530 // Local Variables: // 531 // mode: c // 532 // tab-width: 4 // 533 // End: // -
src/libcfa/concurrency/preemption.c
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Mon Jun 5 14:20:42 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:36:05 2017 13 // Update Count : 2 15 14 // 16 15 … … 34 33 #endif 35 34 35 //TODO move to defaults 36 36 #define __CFA_DEFAULT_PREEMPTION__ 10000 37 37 38 //TODO move to defaults 38 39 __attribute__((weak)) unsigned int default_preemption() { 39 40 return __CFA_DEFAULT_PREEMPTION__; 40 41 } 41 42 43 // Short hands for signal context information 42 44 #define __CFA_SIGCXT__ ucontext_t * 43 45 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt 44 46 47 // FwdDeclarations : timeout handlers 45 48 static void preempt( processor * this ); 46 49 static void timeout( thread_desc * this ); 47 50 51 // FwdDeclarations : Signal handlers 48 52 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ); 49 void sigHandler_alarm ( __CFA_SIGPARMS__ );50 53 void sigHandler_segv ( __CFA_SIGPARMS__ ); 51 54 void sigHandler_abort ( __CFA_SIGPARMS__ ); 52 55 56 // FwdDeclarations : sigaction wrapper 53 57 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ); 54 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 55 58 59 // FwdDeclarations : alarm thread main 60 void * alarm_loop( __attribute__((unused)) void * args ); 61 62 // Machine specific register name 56 63 #ifdef __x86_64__ 57 64 #define CFA_REG_IP REG_RIP … … 60 67 #endif 61 68 69 KERNEL_STORAGE(event_kernel_t, event_kernel); // private storage for event kernel 70 event_kernel_t * event_kernel; // kernel public handle to even kernel 71 static pthread_t alarm_thread; // pthread handle to alarm thread 72 73 void ?{}(event_kernel_t & this) { 74 (this.alarms){}; 75 (this.lock){}; 76 } 62 77 63 78 //============================================================================================= … … 65 80 //============================================================================================= 66 81 82 // Get next expired node 83 static inline alarm_node_t * get_expired( alarm_list_t * alarms, __cfa_time_t currtime ) { 84 if( !alarms->head ) return NULL; // If no alarms return null 85 if( alarms->head->alarm >= currtime ) return NULL; // If alarms head not expired return null 86 return pop(alarms); // Otherwise just pop head 87 } 88 89 // Tick one frame of the Discrete Event Simulation for alarms 67 90 void tick_preemption() { 68 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Ticking preemption\n" );69 70 alarm_list_t * alarms = &systemProcessor->alarms;71 __cfa_time_t currtime = __kernel_get_time(); 72 while( alarms->head && alarms->head->alarm < currtime ) {73 alarm_node_t * node = pop(alarms);74 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking %p\n", node ); 75 91 alarm_node_t * node = NULL; // Used in the while loop but cannot be declared in the while condition 92 alarm_list_t * alarms = &event_kernel->alarms; // Local copy for ease of reading 93 __cfa_time_t currtime = __kernel_get_time(); // Check current time once so we everything "happens at once" 94 95 //Loop throught every thing expired 96 while( node = get_expired( alarms, currtime ) ) { 97 98 // Check if this is a kernel 76 99 if( node->kernel_alarm ) { 77 100 preempt( node->proc ); … … 81 104 } 82 105 83 verify( validate( alarms ) );84 85 if( node->period > 0 ) {86 node->alarm = currtime + node->period;87 insert( alarms, node ); 106 // Check if this is a periodic alarm 107 __cfa_time_t period = node->period; 108 if( period > 0 ) { 109 node->alarm = currtime + period; // Alarm is periodic, add currtime to it (used cached current time) 110 insert( alarms, node ); // Reinsert the node for the next time it triggers 88 111 } 89 112 else { 90 node->set = false; 91 } 92 } 93 94 if( alarms->head ) { 95 __kernel_set_timer( alarms->head->alarm - currtime ); 96 } 97 98 verify( validate( alarms ) ); 99 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Ticking preemption done\n" ); 100 } 101 113 node->set = false; // Node is one-shot, just mark it as not pending 114 } 115 } 116 117 // If there are still alarms pending, reset the timer 118 if( alarms->head ) { __kernel_set_timer( alarms->head->alarm - currtime ); } 119 } 120 121 // Update the preemption of a processor and notify interested parties 102 122 void update_preemption( processor * this, __cfa_time_t duration ) { 103 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Processor : %p updating preemption to %lu\n", this, duration );104 105 123 alarm_node_t * alarm = this->preemption_alarm; 106 duration *= 1000;107 124 108 125 // Alarms need to be enabled … … 134 151 135 152 extern "C" { 153 // Disable interrupts by incrementing the counter 136 154 void disable_interrupts() { 137 155 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 138 verify( new_val < (unsigned short)65_000 ); 139 verify( new_val != (unsigned short) 0 ); 140 } 141 142 void enable_interrupts_noRF() { 143 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 144 verify( prev != (unsigned short) 0 ); 145 } 146 156 verify( new_val < 65_000u ); // If this triggers someone is disabling interrupts without enabling them 157 } 158 159 // Enable interrupts by decrementing the counter 160 // If counter reaches 0, execute any pending CtxSwitch 147 161 void enable_interrupts( DEBUG_CTX_PARAM ) { 148 processor * proc = this_processor; 149 thread_desc * thrd = this_thread; 162 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 163 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add 164 150 165 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 151 verify( prev != (unsigned short) 0 ); 166 verify( prev != 0u ); // If this triggers someone is enabled already enabled interruptsverify( prev != 0u ); 167 168 // Check if we need to prempt the thread because an interrupt was missed 152 169 if( prev == 1 && proc->pending_preemption ) { 153 170 proc->pending_preemption = false; … … 155 172 } 156 173 174 // For debugging purposes : keep track of the last person to enable the interrupts 157 175 LIB_DEBUG_DO( proc->last_enable = caller; ) 158 176 } 159 } 160 177 178 // Disable interrupts by incrementint the counter 179 // Don't execute any pending CtxSwitch even if counter reaches 0 180 void enable_interrupts_noPoll() { 181 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 182 verify( prev != 0u ); // If this triggers someone is enabled already enabled interrupts 183 } 184 } 185 186 // sigprocmask wrapper : unblock a single signal 161 187 static inline void signal_unblock( int sig ) { 162 188 sigset_t mask; … … 169 195 } 170 196 197 // sigprocmask wrapper : block a single signal 171 198 static inline void signal_block( int sig ) { 172 199 sigset_t mask; … … 179 206 } 180 207 181 static inline bool preemption_ready() { 182 return disable_preempt_count == 0 && !preemption_in_progress; 183 } 184 185 static inline void defer_ctxSwitch() { 186 this_processor->pending_preemption = true; 187 } 188 189 static inline void defer_alarm() { 190 systemProcessor->pending_alarm = true; 191 } 192 208 // kill wrapper : signal a processor 193 209 static void preempt( processor * this ) { 194 210 pthread_kill( this->kernel_thread, SIGUSR1 ); 195 211 } 196 212 213 // reserved for future use 197 214 static void timeout( thread_desc * this ) { 198 215 //TODO : implement waking threads 199 216 } 200 217 218 219 // Check if a CtxSwitch signal handler shoud defer 220 // If true : preemption is safe 221 // If false : preemption is unsafe and marked as pending 222 static inline bool preemption_ready() { 223 bool ready = disable_preempt_count == 0 && !preemption_in_progress; // Check if preemption is safe 224 this_processor->pending_preemption = !ready; // Adjust the pending flag accordingly 225 return ready; 226 } 227 201 228 //============================================================================================= 202 229 // Kernel Signal Startup/Shutdown logic 203 230 //============================================================================================= 204 231 205 static pthread_t alarm_thread; 206 void * alarm_loop( __attribute__((unused)) void * args ); 207 232 // Startup routine to activate preemption 233 // Called from kernel_startup 208 234 void kernel_start_preemption() { 209 235 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n"); 210 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); 211 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); 212 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); 236 237 // Start with preemption disabled until ready 238 disable_preempt_count = 1; 239 240 // Initialize the event kernel 241 event_kernel = (event_kernel_t *)&storage_event_kernel; 242 (*event_kernel){}; 243 244 // Setup proper signal handlers 245 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); // CtxSwitch handler 246 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler 247 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler 213 248 214 249 signal_block( SIGALRM ); … … 217 252 } 218 253 254 // Shutdown routine to deactivate preemption 255 // Called from kernel_shutdown 219 256 void kernel_stop_preemption() { 220 257 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n"); 221 258 259 // Block all signals since we are already shutting down 222 260 sigset_t mask; 223 261 sigfillset( &mask ); 224 262 sigprocmask( SIG_BLOCK, &mask, NULL ); 225 263 264 // Notify the alarm thread of the shutdown 226 265 sigval val = { 1 }; 227 266 pthread_sigqueue( alarm_thread, SIGALRM, val ); 267 268 // Wait for the preemption thread to finish 228 269 pthread_join( alarm_thread, NULL ); 270 271 // Preemption is now fully stopped 272 229 273 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n"); 230 274 } 231 275 276 // Raii ctor/dtor for the preemption_scope 277 // Used by thread to control when they want to receive preemption signals 232 278 void ?{}( preemption_scope & this, processor * proc ) { 233 (this.alarm){ proc };279 (this.alarm){ proc, zero_time, zero_time }; 234 280 this.proc = proc; 235 281 this.proc->preemption_alarm = &this.alarm; 236 update_preemption( this.proc, this.proc->preemption ); 282 283 update_preemption( this.proc, from_us(this.proc->cltr->preemption) ); 237 284 } 238 285 … … 240 287 disable_interrupts(); 241 288 242 update_preemption( this.proc, 0);289 update_preemption( this.proc, zero_time ); 243 290 } 244 291 … … 247 294 //============================================================================================= 248 295 296 // Context switch signal handler 297 // Receives SIGUSR1 signal and causes the current thread to yield 249 298 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 250 299 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 251 if( preemption_ready() ) { 252 preemption_in_progress = true; 253 signal_unblock( SIGUSR1 ); 254 this_processor->pending_preemption = false; 255 preemption_in_progress = false; 256 BlockInternal( (thread_desc*)this_thread ); 257 } 258 else { 259 defer_ctxSwitch(); 260 } 261 } 262 300 301 // Check if it is safe to preempt here 302 if( !preemption_ready() ) { return; } 303 304 preemption_in_progress = true; // Sync flag : prevent recursive calls to the signal handler 305 signal_unblock( SIGUSR1 ); // We are about to CtxSwitch out of the signal handler, let other handlers in 306 preemption_in_progress = false; // Clear the in progress flag 307 308 // Preemption can occur here 309 310 BlockInternal( (thread_desc*)this_thread ); // Do the actual CtxSwitch 311 } 312 313 // Main of the alarm thread 314 // Waits on SIGALRM and send SIGUSR1 to whom ever needs it 263 315 void * alarm_loop( __attribute__((unused)) void * args ) { 316 // Block sigalrms to control when they arrive 264 317 sigset_t mask; 265 318 sigemptyset( &mask ); … … 270 323 } 271 324 325 // Main loop 272 326 while( true ) { 327 // Wait for a sigalrm 273 328 siginfo_t info; 274 329 int sig = sigwaitinfo( &mask, &info ); 275 if( sig < 0 ) { 276 abortf( "internal error, sigwait" ); 277 } 278 else if( sig == SIGALRM ) 330 331 // If another signal arrived something went wrong 332 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 333 334 LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int ); 335 // Switch on the code (a.k.a. the sender) to 336 switch( info.si_code ) 279 337 { 280 LIB_DEBUG_PRINT_SAFE("Kernel : Caught signal %d (%d)\n", sig, info.si_value.sival_int ); 281 if( info.si_value.sival_int == 0 ) 282 { 283 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 284 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 285 tick_preemption(); 286 unlock( &systemProcessor->alarm_lock ); 287 } 288 else if( info.si_value.sival_int == 1 ) 289 { 290 break; 291 } 292 } 293 else 294 { 295 LIB_DEBUG_PRINT_SAFE("Kernel : Unexpected signal %d (%d)\n", sig, info.si_value.sival_int); 296 } 297 } 298 338 // Timers can apparently be marked as sent for the kernel 339 // In either case, tick preemption 340 case SI_TIMER: 341 case SI_KERNEL: 342 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 343 lock( &event_kernel->lock DEBUG_CTX2 ); 344 tick_preemption(); 345 unlock( &event_kernel->lock ); 346 break; 347 // Signal was not sent by the kernel but by an other thread 348 case SI_QUEUE: 349 // For now, other thread only signal the alarm thread to shut it down 350 // If this needs to change use info.si_value and handle the case here 351 goto EXIT; 352 } 353 } 354 355 EXIT: 299 356 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n"); 300 357 return NULL; 301 358 } 302 359 360 // Sigaction wrapper : register an signal handler 303 361 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) { 304 362 struct sigaction act; … … 316 374 } 317 375 318 typedef void (*sa_handler_t)(int); 319 376 // Sigaction wrapper : restore default handler 320 377 static void __kernel_sigdefault( int sig ) { 321 378 struct sigaction act; 322 379 323 //act.sa_handler = SIG_DFL;380 act.sa_handler = SIG_DFL; 324 381 act.sa_flags = 0; 325 382 sigemptyset( &act.sa_mask ); … … 429 486 // raise( SIGABRT ); 430 487 // } 488 489 // Local Variables: // 490 // mode: c // 491 // tab-width: 4 // 492 // End: // -
src/libcfa/concurrency/preemption.h
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Mon Jun 5 14:20:42 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:34:25 2017 13 // Update Count : 1 15 14 // 16 15 17 #ifndef PREEMPTION_H 18 #define PREEMPTION_H 16 #pragma once 19 17 20 18 #include "alarm.h" … … 35 33 void ^?{}( preemption_scope & this ); 36 34 37 #endif //PREEMPTION_H 35 // Local Variables: // 36 // mode: c // 37 // tab-width: 4 // 38 // End: // -
src/libcfa/concurrency/thread
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:59:40 2017 13 // Update Count : 3 15 14 // 16 15 17 #ifndef THREADS_H 18 #define THREADS_H 16 #pragma once 19 17 20 #include "assert"18 #include <assert.h> 21 19 #include "invoke.h" 22 20 … … 54 52 } 55 53 56 extern volatile thread_local thread_desc *this_thread;54 extern thread_local thread_desc * volatile this_thread; 57 55 58 56 forall( dtype T | is_thread(T) ) … … 84 82 void yield( unsigned times ); 85 83 86 #endif //THREADS_H87 88 84 // Local Variables: // 89 85 // mode: c // -
src/libcfa/concurrency/thread.c
rfd344aa r9236060 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:34:46 2017 13 // Update Count : 1 15 14 // 16 15 … … 87 86 88 87 void yield( void ) { 89 BlockInternal( (thread_desc *)this_thread );88 BlockInternal( this_thread ); 90 89 } 91 90
Note:
See TracChangeset
for help on using the changeset viewer.