Changes in src/libcfa/concurrency/invoke.h [549c006:ea7d2b0]
- File:
-
- 1 edited
-
src/libcfa/concurrency/invoke.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.h
r549c006 rea7d2b0 14 14 // 15 15 16 #include <stdbool.h>17 #include <stdint.h>16 #include "bits/defs.h" 17 #include "bits/locks.h" 18 18 19 19 #ifdef __CFORALL__ … … 25 25 #define _INVOKE_H_ 26 26 27 #define unlikely(x) __builtin_expect(!!(x), 0) 28 #define thread_local _Thread_local 29 30 typedef void (*fptr_t)(); 31 32 struct spinlock { 33 volatile int lock; 34 #ifdef __CFA_DEBUG__ 35 const char * prev_name; 36 void* prev_thrd; 37 #endif 38 }; 39 40 struct __thread_queue_t { 41 struct thread_desc * head; 42 struct thread_desc ** tail; 43 }; 44 45 struct __condition_stack_t { 46 struct __condition_criterion_t * top; 47 }; 48 49 #ifdef __CFORALL__ 50 extern "Cforall" { 51 void ?{}( struct __thread_queue_t & ); 52 void append( struct __thread_queue_t *, struct thread_desc * ); 53 struct thread_desc * pop_head( struct __thread_queue_t * ); 54 struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** ); 55 56 void ?{}( struct __condition_stack_t & ); 57 void push( struct __condition_stack_t *, struct __condition_criterion_t * ); 58 struct __condition_criterion_t * pop( struct __condition_stack_t * ); 59 60 void ?{}(spinlock & this); 61 void ^?{}(spinlock & this); 62 } 63 #endif 64 65 struct coStack_t { 66 unsigned int size; // size of stack 67 void *storage; // pointer to stack 68 void *limit; // stack grows towards stack limit 69 void *base; // base of stack 70 void *context; // address of cfa_context_t 71 void *top; // address of top of storage 72 bool userStack; // whether or not the user allocated the stack 73 }; 74 75 enum coroutine_state { Halted, Start, Inactive, Active, Primed }; 76 77 struct coroutine_desc { 78 struct coStack_t stack; // stack information of the coroutine 79 const char *name; // textual name for coroutine/task, initialized by uC++ generated code 80 int errno_; // copy of global UNIX variable errno 81 enum coroutine_state state; // current execution status for coroutine 82 struct coroutine_desc * starter; // first coroutine to resume this one 83 struct coroutine_desc * last; // last coroutine to resume this one 84 }; 85 86 struct __waitfor_mask_t { 87 short * accepted; // the index of the accepted function, -1 if none 88 struct __acceptable_t * clauses; // list of acceptable functions, null if any 89 short size; // number of acceptable functions 90 }; 91 92 struct monitor_desc { 93 struct spinlock lock; // spinlock to protect internal data 94 struct thread_desc * owner; // current owner of the monitor 95 struct __thread_queue_t entry_queue; // queue of threads that are blocked waiting for the monitor 96 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 97 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor 99 struct __condition_node_t * dtor_node; // node used to signal the dtor in a waitfor dtor 100 }; 101 102 struct __monitor_group_t { 103 struct monitor_desc ** list; // currently held monitors 104 short size; // number of currently held monitors 105 fptr_t func; // last function that acquired monitors 106 }; 107 108 struct thread_desc { 109 // Core threading fields 110 struct coroutine_desc self_cor; // coroutine body used to store context 111 struct monitor_desc self_mon; // monitor body used for mutual exclusion 112 struct monitor_desc * self_mon_p; // pointer to monitor with sufficient lifetime for current monitors 113 struct __monitor_group_t monitors; // monitors currently held by this thread 114 115 // Link lists fields 116 struct thread_desc * next; // instrusive link field for threads 117 118 27 typedef void (*fptr_t)(); 28 typedef int_fast16_t __lock_size_t; 29 30 struct __thread_queue_t { 31 struct thread_desc * head; 32 struct thread_desc ** tail; 33 }; 34 35 struct __condition_stack_t { 36 struct __condition_criterion_t * top; 37 }; 38 39 #ifdef __CFORALL__ 40 extern "Cforall" { 41 void ?{}( struct __thread_queue_t & ); 42 void append( struct __thread_queue_t &, struct thread_desc * ); 43 struct thread_desc * pop_head( struct __thread_queue_t & ); 44 struct thread_desc * remove( struct __thread_queue_t &, struct thread_desc ** ); 45 46 void ?{}( struct __condition_stack_t & ); 47 void push( struct __condition_stack_t &, struct __condition_criterion_t * ); 48 struct __condition_criterion_t * pop( struct __condition_stack_t & ); 49 } 50 #endif 51 52 struct coStack_t { 53 // size of stack 54 size_t size; 55 56 // pointer to stack 57 void *storage; 58 59 // stack grows towards stack limit 60 void *limit; 61 62 // base of stack 63 void *base; 64 65 // address of cfa_context_t 66 void *context; 67 68 // address of top of storage 69 void *top; 70 71 // whether or not the user allocated the stack 72 bool userStack; 73 }; 74 75 enum coroutine_state { Halted, Start, Inactive, Active, Primed }; 76 77 struct coroutine_desc { 78 // stack information of the coroutine 79 struct coStack_t stack; 80 81 // textual name for coroutine/task, initialized by uC++ generated code 82 const char *name; 83 84 // copy of global UNIX variable errno 85 int errno_; 86 87 // current execution status for coroutine 88 enum coroutine_state state; 89 90 // first coroutine to resume this one 91 struct coroutine_desc * starter; 92 93 // last coroutine to resume this one 94 struct coroutine_desc * last; 95 }; 96 97 struct __waitfor_mask_t { 98 // the index of the accepted function, -1 if none 99 short * accepted; 100 101 // list of acceptable functions, null if any 102 struct __acceptable_t * clauses; 103 104 // number of acceptable functions 105 __lock_size_t size; 106 }; 107 108 struct monitor_desc { 109 // spinlock to protect internal data 110 struct __spinlock_t lock; 111 112 // current owner of the monitor 113 struct thread_desc * owner; 114 115 // queue of threads that are blocked waiting for the monitor 116 struct __thread_queue_t entry_queue; 117 118 // stack of conditions to run next once we exit the monitor 119 struct __condition_stack_t signal_stack; 120 121 // monitor routines can be called recursively, we need to keep track of that 122 unsigned int recursion; 123 124 // mask used to know if some thread is waiting for something while holding the monitor 125 struct __waitfor_mask_t mask; 126 127 // node used to signal the dtor in a waitfor dtor 128 struct __condition_node_t * dtor_node; 129 }; 130 131 struct __monitor_group_t { 132 // currently held monitors 133 struct monitor_desc ** list; 134 135 // number of currently held monitors 136 __lock_size_t size; 137 138 // last function that acquired monitors 139 fptr_t func; 140 }; 141 142 struct thread_desc { 143 // Core threading fields 144 // coroutine body used to store context 145 struct coroutine_desc self_cor; 146 147 // monitor body used for mutual exclusion 148 struct monitor_desc self_mon; 149 150 // pointer to monitor with sufficient lifetime for current monitors 151 struct monitor_desc * self_mon_p; 152 153 // monitors currently held by this thread 154 struct __monitor_group_t monitors; 155 156 // Link lists fields 157 // instrusive link field for threads 158 struct thread_desc * next; 119 159 }; 120 160 121 161 #ifdef __CFORALL__ 122 162 extern "Cforall" { 123 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {124 return this.list[index];125 }126 127 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {128 if( (lhs.list != 0) != (rhs.list != 0) ) return false;129 if( lhs.size != rhs.size ) return false;130 if( lhs.func != rhs.func ) return false;131 132 // Check that all the monitors match133 for( int i = 0; i < lhs.size; i++ ) {134 // If not a match, check next function135 if( lhs[i] != rhs[i] ) return false;136 }137 138 return true;139 }140 }141 #endif163 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) { 164 return this.list[index]; 165 } 166 167 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) { 168 if( (lhs.list != 0) != (rhs.list != 0) ) return false; 169 if( lhs.size != rhs.size ) return false; 170 if( lhs.func != rhs.func ) return false; 171 172 // Check that all the monitors match 173 for( int i = 0; i < lhs.size; i++ ) { 174 // If not a match, check next function 175 if( lhs[i] != rhs[i] ) return false; 176 } 177 178 return true; 179 } 180 } 181 #endif 142 182 143 183 #endif //_INVOKE_H_ … … 146 186 #define _INVOKE_PRIVATE_H_ 147 187 148 struct machine_context_t {149 void *SP;150 void *FP;151 void *PC;152 };153 154 // assembler routines that performs the context switch155 extern void CtxInvokeStub( void );156 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");157 158 #if defined( __x86_64__ )159 #define CtxGet( ctx ) __asm__ ( \160 "movq %%rsp,%0\n" \161 "movq %%rbp,%1\n" \162 : "=rm" (ctx.SP), "=rm" (ctx.FP) )163 #elif defined( __i386__ )164 #define CtxGet( ctx ) __asm__ ( \165 "movl %%esp,%0\n" \166 "movl %%ebp,%1\n" \167 : "=rm" (ctx.SP), "=rm" (ctx.FP) )168 #endif188 struct machine_context_t { 189 void *SP; 190 void *FP; 191 void *PC; 192 }; 193 194 // assembler routines that performs the context switch 195 extern void CtxInvokeStub( void ); 196 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch"); 197 198 #if defined( __x86_64__ ) 199 #define CtxGet( ctx ) __asm__ ( \ 200 "movq %%rsp,%0\n" \ 201 "movq %%rbp,%1\n" \ 202 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 203 #elif defined( __i386__ ) 204 #define CtxGet( ctx ) __asm__ ( \ 205 "movl %%esp,%0\n" \ 206 "movl %%ebp,%1\n" \ 207 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 208 #endif 169 209 170 210 #endif //_INVOKE_PRIVATE_H_
Note:
See TracChangeset
for help on using the changeset viewer.