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