- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel_private.hfa (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel_private.hfa
rc993b15 rfc59df78 25 25 // Scheduler 26 26 27 struct __attribute__((aligned(128))) __scheduler_lock_id_t; 27 28 28 29 extern "C" { 29 30 void disable_interrupts() OPTIONAL_THREAD; 30 void enable_interrupts( bool poll = true ); 31 } 32 33 void schedule_thread$( $thread * ) __attribute__((nonnull (1))); 31 void enable_interrupts_noPoll(); 32 void enable_interrupts( __cfaabi_dbg_ctx_param ); 33 } 34 35 void __schedule_thread( $thread * ) 36 #if defined(NDEBUG) || (!defined(__CFA_DEBUG__) && !defined(__CFA_VERIFY__)) 37 __attribute__((nonnull (1))) 38 #endif 39 ; 34 40 35 41 extern bool __preemption_enabled(); … … 79 85 // Lock-Free registering/unregistering of threads 80 86 // Register a processor to a given cluster and get its unique id in return 81 unsigned register_proc_id( void);87 void register_proc_id( struct __processor_id_t * ); 82 88 83 89 // Unregister a processor from a given cluster using its id, getting back the original pointer 84 void unregister_proc_id( unsigned);90 void unregister_proc_id( struct __processor_id_t * proc ); 85 91 86 92 //======================================================================= … … 111 117 } 112 118 113 114 115 119 // Cells use by the reader writer lock 120 // while not generic it only relies on a opaque pointer 121 struct __attribute__((aligned(128))) __scheduler_lock_id_t { 122 // Spin lock used as the underlying lock 123 volatile bool lock; 124 125 // Handle pointing to the proc owning this cell 126 // Used for allocating cells and debugging 127 __processor_id_t * volatile handle; 128 129 #ifdef __CFA_WITH_VERIFY__ 130 // Debug, check if this is owned for reading 131 bool owned; 132 #endif 133 }; 134 135 static_assert( sizeof(struct __scheduler_lock_id_t) <= __alignof(struct __scheduler_lock_id_t)); 116 136 117 137 //----------------------------------------------------------------------- … … 132 152 133 153 // writer lock 134 volatile bool write_lock;154 volatile bool lock; 135 155 136 156 // data pointer 137 volatile bool * volatile* data;157 __scheduler_lock_id_t * data; 138 158 }; 139 159 … … 148 168 static inline void ready_schedule_lock(void) with(*__scheduler_lock) { 149 169 /* paranoid */ verify( ! __preemption_enabled() ); 150 /* paranoid */ verify( ! kernelTLS().in_sched_lock ); 151 /* paranoid */ verify( data[kernelTLS().sched_id] == &kernelTLS().sched_lock ); 152 /* paranoid */ verify( !kernelTLS().this_processor || kernelTLS().this_processor->unique_id == kernelTLS().sched_id ); 170 /* paranoid */ verify( kernelTLS().this_proc_id ); 171 172 unsigned iproc = kernelTLS().this_proc_id->id; 173 /*paranoid*/ verify(data[iproc].handle == kernelTLS().this_proc_id); 174 /*paranoid*/ verify(iproc < ready); 153 175 154 176 // Step 1 : make sure no writer are in the middle of the critical section 155 while(__atomic_load_n(& write_lock, (int)__ATOMIC_RELAXED))177 while(__atomic_load_n(&lock, (int)__ATOMIC_RELAXED)) 156 178 Pause(); 157 179 … … 162 184 163 185 // Step 2 : acquire our local lock 164 __atomic_acquire( & kernelTLS().sched_lock );165 /*paranoid*/ verify( kernelTLS().sched_lock);186 __atomic_acquire( &data[iproc].lock ); 187 /*paranoid*/ verify(data[iproc].lock); 166 188 167 189 #ifdef __CFA_WITH_VERIFY__ 168 190 // Debug, check if this is owned for reading 169 kernelTLS().in_sched_lock= true;191 data[iproc].owned = true; 170 192 #endif 171 193 } … … 173 195 static inline void ready_schedule_unlock(void) with(*__scheduler_lock) { 174 196 /* paranoid */ verify( ! __preemption_enabled() ); 175 /* paranoid */ verify( data[kernelTLS().sched_id] == &kernelTLS().sched_lock ); 176 /* paranoid */ verify( !kernelTLS().this_processor || kernelTLS().this_processor->unique_id == kernelTLS().sched_id ); 177 /* paranoid */ verify( kernelTLS().sched_lock ); 178 /* paranoid */ verify( kernelTLS().in_sched_lock ); 197 /* paranoid */ verify( kernelTLS().this_proc_id ); 198 199 unsigned iproc = kernelTLS().this_proc_id->id; 200 /*paranoid*/ verify(data[iproc].handle == kernelTLS().this_proc_id); 201 /*paranoid*/ verify(iproc < ready); 202 /*paranoid*/ verify(data[iproc].lock); 203 /*paranoid*/ verify(data[iproc].owned); 179 204 #ifdef __CFA_WITH_VERIFY__ 180 205 // Debug, check if this is owned for reading 181 kernelTLS().in_sched_lock= false;206 data[iproc].owned = false; 182 207 #endif 183 __atomic_unlock(& kernelTLS().sched_lock);208 __atomic_unlock(&data[iproc].lock); 184 209 } 185 210 … … 187 212 static inline bool ready_schedule_islocked(void) { 188 213 /* paranoid */ verify( ! __preemption_enabled() ); 189 /* paranoid */ verify( (!kernelTLS().in_sched_lock) || kernelTLS().sched_lock ); 190 return kernelTLS().sched_lock; 214 /*paranoid*/ verify( kernelTLS().this_proc_id ); 215 __processor_id_t * proc = kernelTLS().this_proc_id; 216 return __scheduler_lock->data[proc->id].owned; 191 217 } 192 218 193 219 static inline bool ready_mutate_islocked() { 194 return __scheduler_lock-> write_lock;220 return __scheduler_lock->lock; 195 221 } 196 222 #endif … … 207 233 // Register a processor to a given cluster and get its unique id in return 208 234 // For convenience, also acquires the lock 209 static inline [unsigned, uint_fast32_t] ready_mutate_register() { 210 unsigned id = register_proc_id(); 211 uint_fast32_t last = ready_mutate_lock(); 212 return [id, last]; 235 static inline uint_fast32_t ready_mutate_register( struct __processor_id_t * proc ) { 236 register_proc_id( proc ); 237 return ready_mutate_lock(); 213 238 } 214 239 215 240 // Unregister a processor from a given cluster using its id, getting back the original pointer 216 241 // assumes the lock is acquired 217 static inline void ready_mutate_unregister( unsigned id, uint_fast32_t last_s ) {242 static inline void ready_mutate_unregister( struct __processor_id_t * proc, uint_fast32_t last_s ) { 218 243 ready_mutate_unlock( last_s ); 219 unregister_proc_id( id);244 unregister_proc_id( proc ); 220 245 } 221 246
Note:
See TracChangeset
for help on using the changeset viewer.