Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/cluster.cfa

    rcd3fc46 r5024df4  
    9393//=======================================================================
    9494void  ?{}(__scheduler_RWLock_t & this) {
    95         this.lock.max   = __max_processors();
    96         this.lock.alloc = 0;
    97         this.lock.ready = 0;
    98         this.lock.data  = alloc(this.lock.max);
    99         this.lock.write_lock  = false;
    100 
    101         /*paranoid*/ verify(__atomic_is_lock_free(sizeof(this.lock.alloc), &this.lock.alloc));
    102         /*paranoid*/ verify(__atomic_is_lock_free(sizeof(this.lock.ready), &this.lock.ready));
     95        this.max   = __max_processors();
     96        this.alloc = 0;
     97        this.ready = 0;
     98        this.data  = alloc(this.max);
     99        this.write_lock  = false;
     100
     101        /*paranoid*/ verify(__atomic_is_lock_free(sizeof(this.alloc), &this.alloc));
     102        /*paranoid*/ verify(__atomic_is_lock_free(sizeof(this.ready), &this.ready));
    103103
    104104}
    105105void ^?{}(__scheduler_RWLock_t & this) {
    106         free(this.lock.data);
     106        free(this.data);
    107107}
    108108
     
    110110//=======================================================================
    111111// Lock-Free registering/unregistering of threads
    112 unsigned register_proc_id( void ) with(__scheduler_lock.lock) {
     112unsigned register_proc_id( void ) with(*__scheduler_lock) {
    113113        __kernel_rseq_register();
    114114
     
    132132        }
    133133
    134         if(max <= alloc) abort("Trying to create more than %ud processors", __scheduler_lock.lock.max);
     134        if(max <= alloc) abort("Trying to create more than %ud processors", __scheduler_lock->max);
    135135
    136136        // Step - 2 : F&A to get a new spot in the array.
    137137        uint_fast32_t n = __atomic_fetch_add(&alloc, 1, __ATOMIC_SEQ_CST);
    138         if(max <= n) abort("Trying to create more than %ud processors", __scheduler_lock.lock.max);
     138        if(max <= n) abort("Trying to create more than %ud processors", __scheduler_lock->max);
    139139
    140140        // Step - 3 : Mark space as used and then publish it.
     
    154154}
    155155
    156 void unregister_proc_id( unsigned id ) with(__scheduler_lock.lock) {
     156void unregister_proc_id( unsigned id ) with(*__scheduler_lock) {
    157157        /* paranoid */ verify(id < ready);
    158158        /* paranoid */ verify(id == kernelTLS().sched_id);
     
    169169// Writer side : acquire when changing the ready queue, e.g. adding more
    170170//  queues or removing them.
    171 uint_fast32_t ready_mutate_lock( void ) with(__scheduler_lock.lock) {
     171uint_fast32_t ready_mutate_lock( void ) with(*__scheduler_lock) {
    172172        /* paranoid */ verify( ! __preemption_enabled() );
    173173
     
    196196}
    197197
    198 void ready_mutate_unlock( uint_fast32_t last_s ) with(__scheduler_lock.lock) {
     198void ready_mutate_unlock( uint_fast32_t last_s ) with(*__scheduler_lock) {
    199199        /* paranoid */ verify( ! __preemption_enabled() );
    200200
     
    229229                        for( idx ; lanes_count ) {
    230230                                __intrusive_lane_t & sl = readyQ.data[idx];
    231                                 assert(!readyQ.data[idx].l.lock);
     231                                assert(!readyQ.data[idx].lock);
    232232
    233233                                        if(is_empty(sl)) {
    234                                                 assert( sl.l.anchor.next == 0p );
    235                                                 assert( sl.l.anchor.ts   == MAX );
    236                                                 assert( mock_head(sl)  == sl.l.prev );
     234                                                assert( sl.anchor.next == 0p );
     235                                                assert( sl.anchor.ts   == MAX );
     236                                                assert( mock_head(sl)  == sl.prev );
    237237                                        } else {
    238                                                 assert( sl.l.anchor.next != 0p );
    239                                                 assert( sl.l.anchor.ts   != MAX );
    240                                                 assert( mock_head(sl)  != sl.l.prev );
     238                                                assert( sl.anchor.next != 0p );
     239                                                assert( sl.anchor.ts   != MAX );
     240                                                assert( mock_head(sl)  != sl.prev );
    241241                                        }
    242242                        }
     
    249249static inline void fix(__intrusive_lane_t & ll) {
    250250        if(is_empty(ll)) {
    251                 verify(ll.l.anchor.next == 0p);
    252                 ll.l.prev = mock_head(ll);
     251                verify(ll.anchor.next == 0p);
     252                ll.prev = mock_head(ll);
    253253        }
    254254}
     
    278278
    279279#if defined(CFA_HAVE_LINUX_IO_URING_H)
    280         static void assign_io(io_context$ ** data, size_t count, dlist(processor) & list) {
     280        static void assign_io($io_context ** data, size_t count, dlist(processor) & list) {
    281281                processor * it = &list`first;
    282282                while(it) {
     
    299299        tscs = alloc(count, tscs`realloc);
    300300        for(i; count) {
    301                 tscs[i].t.tv = rdtscl();
    302                 tscs[i].t.ma = 0;
     301                tscs[i].tv = rdtscl();
     302                tscs[i].ma = 0;
    303303        }
    304304}
     
    400400                for( idx; ncount ~ ocount) {
    401401                        // Lock is not strictly needed but makes checking invariants much easier
    402                         __attribute__((unused)) bool locked = __atomic_try_acquire(&readyQ.data[idx].l.lock);
     402                        __attribute__((unused)) bool locked = __atomic_try_acquire(&readyQ.data[idx].lock);
    403403                        verify(locked);
    404404
     
    418418
    419419                        // Unlock the lane
    420                         __atomic_unlock(&readyQ.data[idx].l.lock);
     420                        __atomic_unlock(&readyQ.data[idx].lock);
    421421
    422422                        // TODO print the queue statistics here
     
    467467}
    468468
    469 #define nested_offsetof(type, field) ((off_t)(&(((type*)0)-> field)))
    470 
    471469// Ctor
    472470void ?{}( __intrusive_lane_t & this ) {
    473         this.l.lock = false;
    474         this.l.prev = mock_head(this);
    475         this.l.anchor.next = 0p;
    476         this.l.anchor.ts   = MAX;
     471        this.lock = false;
     472        this.prev = mock_head(this);
     473        this.anchor.next = 0p;
     474        this.anchor.ts   = MAX;
    477475        #if !defined(__CFA_NO_STATISTICS__)
    478                 this.l.cnt  = 0;
     476                this.cnt  = 0;
    479477        #endif
    480478
    481479        // We add a boat-load of assertions here because the anchor code is very fragile
    482         /* paranoid */ _Static_assert( offsetof( thread$, link ) == nested_offsetof(__intrusive_lane_t, l.anchor) );
    483         /* paranoid */ verify( offsetof( thread$, link ) == nested_offsetof(__intrusive_lane_t, l.anchor) );
    484         /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( thread$, link )) == (uintptr_t)(&this.l.anchor) );
    485         /* paranoid */ verify( &mock_head(this)->link.next == &this.l.anchor.next );
    486         /* paranoid */ verify( &mock_head(this)->link.ts   == &this.l.anchor.ts   );
     480        /* paranoid */ _Static_assert( offsetof( thread$, link ) == offsetof(__intrusive_lane_t, anchor) );
     481        /* paranoid */ verify( offsetof( thread$, link ) == offsetof(__intrusive_lane_t, anchor) );
     482        /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( thread$, link )) == (uintptr_t)(&this.anchor) );
     483        /* paranoid */ verify( &mock_head(this)->link.next == &this.anchor.next );
     484        /* paranoid */ verify( &mock_head(this)->link.ts   == &this.anchor.ts   );
    487485        /* paranoid */ verify( mock_head(this)->link.next == 0p );
    488486        /* paranoid */ verify( mock_head(this)->link.ts   == MAX );
    489         /* paranoid */ verify( mock_head(this) == this.l.prev );
    490         /* paranoid */ verify( __alignof__(__intrusive_lane_t) == 64 );
    491         /* paranoid */ verify( __alignof__(this) == 64 );
    492         /* paranoid */ verifyf( ((intptr_t)(&this) % 64) == 0, "Expected address to be aligned %p %% 64 == %zd", &this, ((intptr_t)(&this) % 64) );
    493 }
    494 
    495 #undef nested_offsetof
     487        /* paranoid */ verify( mock_head(this) == this.prev );
     488        /* paranoid */ verify( __alignof__(__intrusive_lane_t) == 128 );
     489        /* paranoid */ verify( __alignof__(this) == 128 );
     490        /* paranoid */ verifyf( ((intptr_t)(&this) % 128) == 0, "Expected address to be aligned %p %% 128 == %zd", &this, ((intptr_t)(&this) % 128) );
     491}
    496492
    497493// Dtor is trivial
    498494void ^?{}( __intrusive_lane_t & this ) {
    499495        // Make sure the list is empty
    500         /* paranoid */ verify( this.l.anchor.next == 0p );
    501         /* paranoid */ verify( this.l.anchor.ts   == MAX );
    502         /* paranoid */ verify( mock_head(this)    == this.l.prev );
     496        /* paranoid */ verify( this.anchor.next == 0p );
     497        /* paranoid */ verify( this.anchor.ts   == MAX );
     498        /* paranoid */ verify( mock_head(this)  == this.prev );
    503499}
    504500
Note: See TracChangeset for help on using the changeset viewer.