Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/ready_queue.cfa

    rc993b15 rd3ba775  
    1717// #define __CFA_DEBUG_PRINT_READY_QUEUE__
    1818
    19 // #define USE_MPSC
    2019
    2120#define USE_RELAXED_FIFO
     
    256255                /* paranoid */ verify(external || kernelTLS().this_processor->rdq.id < lanes.count );
    257256
    258                 // write timestamp
    259                 thrd->link.ts = rdtscl();
    260 
    261257                bool local;
    262258                int preferred = external ? -1 : kernelTLS().this_processor->rdq.id;
     
    277273                        #endif
    278274
    279                 #if defined(USE_MPSC)
    280                         // mpsc always succeeds
    281                 } while( false );
    282                 #else
    283275                        // If we can't lock it retry
    284276                } while( !__atomic_try_acquire( &lanes.data[i].lock ) );
    285                 #endif
    286277
    287278                // Actually push it
    288279                push(lanes.data[i], thrd);
    289280
    290                 #if !defined(USE_MPSC)
    291281                        // Unlock and return
    292282                        __atomic_unlock( &lanes.data[i].lock );
    293                 #endif
    294283
    295284                // Mark the current index in the tls rng instance as having an item
     
    350339                __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr);
    351340
     341                // #define USE_PREFERRED
     342                #if !defined(USE_PREFERRED)
    352343                const bool external = (!kernelTLS().this_processor) || (cltr != kernelTLS().this_processor->cltr);
    353344                /* paranoid */ verify(external || kernelTLS().this_processor->rdq.id < lanes.count );
    354 
    355                 // write timestamp
    356                 thrd->link.ts = rdtscl();
     345                #else
     346                        unsigned preferred = thrd->preferred;
     347                        const bool external = (!kernelTLS().this_processor) || preferred == -1u || thrd->curr_cluster != cltr;
     348                        /* paranoid */ verifyf(external || preferred < lanes.count, "Invalid preferred queue %u for %u lanes", preferred, lanes.count );
     349
     350                        unsigned r = preferred % READYQ_SHARD_FACTOR;
     351                        const unsigned start = preferred - r;
     352                #endif
    357353
    358354                // Try to pick a lane and lock it
     
    368364                        }
    369365                        else {
     366                                #if !defined(USE_PREFERRED)
    370367                                processor * proc = kernelTLS().this_processor;
    371368                                unsigned r = proc->rdq.its++;
    372369                                i =  proc->rdq.id + (r % READYQ_SHARD_FACTOR);
     370                #else
     371                                        i = start + (r++ % READYQ_SHARD_FACTOR);
     372                                #endif
    373373                        }
    374 
    375 
    376                 #if defined(USE_MPSC)
    377                         // mpsc always succeeds
    378                 } while( false );
    379                 #else
    380374                        // If we can't lock it retry
    381375                } while( !__atomic_try_acquire( &lanes.data[i].lock ) );
    382                 #endif
    383376
    384377                // Actually push it
    385378                push(lanes.data[i], thrd);
    386379
    387                 #if !defined(USE_MPSC)
    388380                        // Unlock and return
    389381                        __atomic_unlock( &lanes.data[i].lock );
    390                 #endif
    391382
    392383                #if !defined(__CFA_NO_STATISTICS__)
     
    492483                lanes.tscs[w].tv = thrd->link.ts;
    493484        #endif
     485
     486        thrd->preferred = w;
    494487
    495488        // return the popped thread
     
    519512// Check that all the intrusive queues in the data structure are still consistent
    520513static void check( __ready_queue_t & q ) with (q) {
    521         #if defined(__CFA_WITH_VERIFY__) && !defined(USE_MPSC)
     514        #if defined(__CFA_WITH_VERIFY__)
    522515                {
    523516                        for( idx ; lanes.count ) {
     
    525518                                assert(!lanes.data[idx].lock);
    526519
    527                                 assert(head(sl)->link.prev == 0p );
    528                                 assert(head(sl)->link.next->link.prev == head(sl) );
    529                                 assert(tail(sl)->link.next == 0p );
    530                                 assert(tail(sl)->link.prev->link.next == tail(sl) );
    531 
    532                                 if(is_empty(sl)) {
    533                                         assert(tail(sl)->link.prev == head(sl));
    534                                         assert(head(sl)->link.next == tail(sl));
    535                                 } else {
    536                                         assert(tail(sl)->link.prev != head(sl));
    537                                         assert(head(sl)->link.next != tail(sl));
    538                                 }
     520                                        if(is_empty(sl)) {
     521                                                assert( sl.anchor.next == 0p );
     522                                                assert( sl.anchor.ts   == 0  );
     523                                                assert( mock_head(sl)  == sl.prev );
     524                                        } else {
     525                                                assert( sl.anchor.next != 0p );
     526                                                assert( sl.anchor.ts   != 0  );
     527                                                assert( mock_head(sl)  != sl.prev );
     528                                        }
    539529                        }
    540530                }
     
    557547// fixes the list so that the pointers back to anchors aren't left dangling
    558548static inline void fix(__intrusive_lane_t & ll) {
    559         #if !defined(USE_MPSC)
    560                 // if the list is not empty then follow he pointer and fix its reverse
    561                 if(!is_empty(ll)) {
    562                         head(ll)->link.next->link.prev = head(ll);
    563                         tail(ll)->link.prev->link.next = tail(ll);
    564                 }
    565                 // Otherwise just reset the list
    566                 else {
    567                         verify(tail(ll)->link.next == 0p);
    568                         tail(ll)->link.prev = head(ll);
    569                         head(ll)->link.next = tail(ll);
    570                         verify(head(ll)->link.prev == 0p);
    571                 }
    572         #endif
     549                        if(is_empty(ll)) {
     550                                verify(ll.anchor.next == 0p);
     551                                ll.prev = mock_head(ll);
     552                        }
    573553}
    574554
Note: See TracChangeset for help on using the changeset viewer.