Changes in / [e2f601f:69914cbc]
- Location:
- libcfa/src/concurrency
- Files:
-
- 5 edited
-
kernel.cfa (modified) (9 diffs)
-
kernel.hfa (modified) (2 diffs)
-
kernel/startup.cfa (modified) (1 diff)
-
ready_queue.cfa (modified) (2 diffs)
-
ready_subqueue.hfa (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
re2f601f r69914cbc 182 182 MAIN_LOOP: 183 183 for() { 184 #define OLD_MAIN 1 185 #if OLD_MAIN 184 #if 1 186 185 // Check if there is pending io 187 186 __maybe_io_drain( this ); … … 263 262 264 263 #else 265 #warning new kernel loop 264 266 265 SEARCH: { 267 266 /* paranoid */ verify( ! __preemption_enabled() ); 267 /* paranoid */ verify( kernelTLS().this_proc_id ); 268 268 269 269 // First, lock the scheduler since we are searching for a thread … … 278 278 279 279 // Spin a little on I/O, just in case 280 for(5) {280 for(25) { 281 281 __maybe_io_drain( this ); 282 282 readyThread = pop_fast( this->cltr ); … … 285 285 286 286 // no luck, try stealing a few times 287 for(5) {287 for(25) { 288 288 if( __maybe_io_drain( this ) ) { 289 289 readyThread = pop_fast( this->cltr ); … … 323 323 } 324 324 325 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )325 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->id, rdtscl()); ) 326 326 __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle); 327 327 … … 331 331 // __enable_interrupts_hard(); 332 332 333 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )333 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl()); ) 334 334 335 335 // We were woken up, remove self from idle … … 341 341 342 342 RUN_THREAD: 343 /* paranoid */ verify( kernelTLS().this_proc_id ); 343 344 /* paranoid */ verify( ! __preemption_enabled() ); 344 345 /* paranoid */ verify( readyThread ); … … 352 353 // Are we done? 353 354 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP; 355 356 #if !defined(__CFA_NO_STATISTICS__) 357 unsigned long long curr = rdtscl(); 358 if(curr > (last_tally + 500000000)) { 359 __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats); 360 last_tally = curr; 361 } 362 #endif 354 363 355 364 if(this->io.pending && !this->io.dirty) { … … 868 877 unsigned tail = *ctx->cq.tail; 869 878 if(head == tail) return false; 870 #if OLD_MAIN871 879 ready_schedule_lock(); 872 880 ret = __cfa_io_drain( proc ); 873 881 ready_schedule_unlock(); 874 #else875 ret = __cfa_io_drain( proc );876 #endif877 882 #endif 878 883 return ret; -
libcfa/src/concurrency/kernel.hfa
re2f601f r69914cbc 147 147 148 148 // Aligned timestamps which are used by the relaxed ready queue 149 struct __attribute__((aligned(128))) __timestamp_t { 150 volatile unsigned long long tv; 151 }; 152 153 static inline void ?{}(__timestamp_t & this) { this.tv = 0; } 154 static inline void ^?{}(__timestamp_t & this) {} 149 struct __attribute__((aligned(128))) __timestamp_t; 150 void ?{}(__timestamp_t & this); 151 void ^?{}(__timestamp_t & this); 155 152 156 153 //TODO adjust cache size to ARCHITECTURE … … 175 172 void ?{}(__ready_queue_t & this); 176 173 void ^?{}(__ready_queue_t & this); 177 #if !defined(__CFA_NO_STATISTICS__)178 unsigned cnt(const __ready_queue_t & this, unsigned idx);179 #endif180 174 181 175 // Idle Sleep -
libcfa/src/concurrency/kernel/startup.cfa
re2f601f r69914cbc 496 496 this.rdq.id = -1u; 497 497 this.rdq.target = -1u; 498 this.rdq.cutoff = 0ull;498 this.rdq.cutoff = -1ull; 499 499 do_terminate = false; 500 500 preemption_alarm = 0p; -
libcfa/src/concurrency/ready_queue.cfa
re2f601f r69914cbc 398 398 399 399 if(proc->rdq.target == -1u) { 400 unsigned long long min = ts(lanes.data[proc->rdq.id]); 401 for(int i = 0; i < READYQ_SHARD_FACTOR; i++) { 402 unsigned long long tsc = ts(lanes.data[proc->rdq.id + i]); 403 if(tsc < min) min = tsc; 404 } 405 proc->rdq.cutoff = min; 400 _Static_assert(READYQ_SHARD_FACTOR == 2); 401 unsigned idx1 = proc->rdq.id + 0; 402 unsigned idx2 = proc->rdq.id + 1; 403 unsigned long long tsc1 = ts(lanes.data[idx1]); 404 unsigned long long tsc2 = ts(lanes.data[idx2]); 406 405 proc->rdq.target = __tls_rand() % lanes.count; 406 407 // WARNING: std::min is polymorphic and therefore causes 500% slowdown instead of the expected 2% 408 proc->rdq.cutoff = tsc1 < tsc2 ? tsc1 : tsc2; 407 409 } 408 410 else { … … 702 704 /* paranoid */ verify( ready_mutate_islocked() ); 703 705 } 704 705 #if !defined(__CFA_NO_STATISTICS__)706 unsigned cnt(const __ready_queue_t & this, unsigned idx) {707 /* paranoid */ verify(this.lanes.count > idx);708 return this.lanes.data[idx].cnt;709 }710 #endif -
libcfa/src/concurrency/ready_subqueue.hfa
re2f601f r69914cbc 11 11 // spin lock protecting the queue 12 12 volatile bool lock; 13 14 #if !defined(__CFA_NO_STATISTICS__)15 unsigned cnt;16 #endif17 13 18 14 __thread_desc_link anchor; … … 33 29 this.anchor.next = 0p; 34 30 this.anchor.ts = 0; 35 #if !defined(__CFA_NO_STATISTICS__)36 this.cnt = 0;37 #endif38 31 39 32 // We add a boat-load of assertions here because the anchor code is very fragile 40 /* paranoid */ _Static_assert( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) );41 33 /* paranoid */ verify( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) ); 42 34 /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( $thread, link )) == (uintptr_t)(&this.anchor) ); … … 62 54 // returns true of lane was empty before push, false otherwise 63 55 static inline void push( __intrusive_lane_t & this, $thread * node ) { 64 /* paranoid */ verify( this.lock );65 56 /* paranoid */ verify( node->link.next == 0p ); 66 57 /* paranoid */ verify( node->link.ts == 0 ); … … 81 72 this.prev->link.ts = rdtscl(); 82 73 this.prev = node; 83 #if !defined(__CFA_NO_STATISTICS__)84 this.cnt++;85 #endif86 74 } 87 75 … … 90 78 // returns true of lane was empty before push, false otherwise 91 79 static inline [* $thread, unsigned long long] pop( __intrusive_lane_t & this ) { 92 /* paranoid */ verify( this.lock );93 80 /* paranoid */ verify( this.anchor.next != 0p ); 94 81 /* paranoid */ verify( this.anchor.ts != 0 ); … … 102 89 node->link.next = 0p; 103 90 node->link.ts = 0; 104 #if !defined(__CFA_NO_STATISTICS__)105 this.cnt--;106 #endif107 91 108 92 // Update head time stamp … … 124 108 return this.anchor.ts; 125 109 } 110 111 // Aligned timestamps which are used by the relaxed ready queue 112 struct __attribute__((aligned(128))) __timestamp_t { 113 volatile unsigned long long tv; 114 }; 115 116 void ?{}(__timestamp_t & this) { this.tv = 0; } 117 void ^?{}(__timestamp_t & this) {}
Note:
See TracChangeset
for help on using the changeset viewer.