Ignore:
File:
1 edited

Legend:

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

    rd3ba775 rc993b15  
    1717// #define __CFA_DEBUG_PRINT_READY_QUEUE__
    1818
     19// #define USE_MPSC
    1920
    2021#define USE_RELAXED_FIFO
     
    255256                /* paranoid */ verify(external || kernelTLS().this_processor->rdq.id < lanes.count );
    256257
     258                // write timestamp
     259                thrd->link.ts = rdtscl();
     260
    257261                bool local;
    258262                int preferred = external ? -1 : kernelTLS().this_processor->rdq.id;
     
    273277                        #endif
    274278
     279                #if defined(USE_MPSC)
     280                        // mpsc always succeeds
     281                } while( false );
     282                #else
    275283                        // If we can't lock it retry
    276284                } while( !__atomic_try_acquire( &lanes.data[i].lock ) );
     285                #endif
    277286
    278287                // Actually push it
    279288                push(lanes.data[i], thrd);
    280289
     290                #if !defined(USE_MPSC)
    281291                        // Unlock and return
    282292                        __atomic_unlock( &lanes.data[i].lock );
     293                #endif
    283294
    284295                // Mark the current index in the tls rng instance as having an item
     
    339350                __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr);
    340351
    341                 // #define USE_PREFERRED
    342                 #if !defined(USE_PREFERRED)
    343352                const bool external = (!kernelTLS().this_processor) || (cltr != kernelTLS().this_processor->cltr);
    344353                /* paranoid */ verify(external || kernelTLS().this_processor->rdq.id < lanes.count );
    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
     354
     355                // write timestamp
     356                thrd->link.ts = rdtscl();
    353357
    354358                // Try to pick a lane and lock it
     
    364368                        }
    365369                        else {
    366                                 #if !defined(USE_PREFERRED)
    367370                                processor * proc = kernelTLS().this_processor;
    368371                                unsigned r = proc->rdq.its++;
    369372                                i =  proc->rdq.id + (r % READYQ_SHARD_FACTOR);
     373                        }
     374
     375
     376                #if defined(USE_MPSC)
     377                        // mpsc always succeeds
     378                } while( false );
    370379                #else
    371                                         i = start + (r++ % READYQ_SHARD_FACTOR);
    372                                 #endif
    373                         }
    374380                        // If we can't lock it retry
    375381                } while( !__atomic_try_acquire( &lanes.data[i].lock ) );
     382                #endif
    376383
    377384                // Actually push it
    378385                push(lanes.data[i], thrd);
    379386
     387                #if !defined(USE_MPSC)
    380388                        // Unlock and return
    381389                        __atomic_unlock( &lanes.data[i].lock );
     390                #endif
    382391
    383392                #if !defined(__CFA_NO_STATISTICS__)
     
    483492                lanes.tscs[w].tv = thrd->link.ts;
    484493        #endif
    485 
    486         thrd->preferred = w;
    487494
    488495        // return the popped thread
     
    512519// Check that all the intrusive queues in the data structure are still consistent
    513520static void check( __ready_queue_t & q ) with (q) {
    514         #if defined(__CFA_WITH_VERIFY__)
     521        #if defined(__CFA_WITH_VERIFY__) && !defined(USE_MPSC)
    515522                {
    516523                        for( idx ; lanes.count ) {
     
    518525                                assert(!lanes.data[idx].lock);
    519526
    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                                         }
     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                                }
    529539                        }
    530540                }
     
    547557// fixes the list so that the pointers back to anchors aren't left dangling
    548558static inline void fix(__intrusive_lane_t & ll) {
    549                         if(is_empty(ll)) {
    550                                 verify(ll.anchor.next == 0p);
    551                                 ll.prev = mock_head(ll);
    552                         }
     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
    553573}
    554574
Note: See TracChangeset for help on using the changeset viewer.