Ignore:
Timestamp:
Jul 28, 2022, 11:59:02 AM (22 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
c4c8571
Parents:
13d326ec
Message:

Small improvements to some of the alignment requirements in CFA runtime.

Location:
libcfa/src/concurrency/kernel
Files:
5 edited

Legend:

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

    r13d326ec r2af1943  
    229229                        for( idx ; lanes_count ) {
    230230                                __intrusive_lane_t & sl = readyQ.data[idx];
    231                                 assert(!readyQ.data[idx].lock);
     231                                assert(!readyQ.data[idx].l.lock);
    232232
    233233                                        if(is_empty(sl)) {
    234                                                 assert( sl.anchor.next == 0p );
    235                                                 assert( sl.anchor.ts   == MAX );
    236                                                 assert( mock_head(sl)  == sl.prev );
     234                                                assert( sl.l.anchor.next == 0p );
     235                                                assert( sl.l.anchor.ts   == MAX );
     236                                                assert( mock_head(sl)  == sl.l.prev );
    237237                                        } else {
    238                                                 assert( sl.anchor.next != 0p );
    239                                                 assert( sl.anchor.ts   != MAX );
    240                                                 assert( mock_head(sl)  != sl.prev );
     238                                                assert( sl.l.anchor.next != 0p );
     239                                                assert( sl.l.anchor.ts   != MAX );
     240                                                assert( mock_head(sl)  != sl.l.prev );
    241241                                        }
    242242                        }
     
    249249static inline void fix(__intrusive_lane_t & ll) {
    250250        if(is_empty(ll)) {
    251                 verify(ll.anchor.next == 0p);
    252                 ll.prev = mock_head(ll);
     251                verify(ll.l.anchor.next == 0p);
     252                ll.l.prev = mock_head(ll);
    253253        }
    254254}
     
    299299        tscs = alloc(count, tscs`realloc);
    300300        for(i; count) {
    301                 tscs[i].tv = rdtscl();
    302                 tscs[i].ma = 0;
     301                tscs[i].t.tv = rdtscl();
     302                tscs[i].t.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].lock);
     402                        __attribute__((unused)) bool locked = __atomic_try_acquire(&readyQ.data[idx].l.lock);
    403403                        verify(locked);
    404404
     
    418418
    419419                        // Unlock the lane
    420                         __atomic_unlock(&readyQ.data[idx].lock);
     420                        __atomic_unlock(&readyQ.data[idx].l.lock);
    421421
    422422                        // TODO print the queue statistics here
     
    467467}
    468468
     469#define nested_offsetof(type, field) ((off_t)(&(((type*)0)-> field)))
     470
    469471// Ctor
    470472void ?{}( __intrusive_lane_t & this ) {
    471         this.lock = false;
    472         this.prev = mock_head(this);
    473         this.anchor.next = 0p;
    474         this.anchor.ts   = MAX;
     473        this.l.lock = false;
     474        this.l.prev = mock_head(this);
     475        this.l.anchor.next = 0p;
     476        this.l.anchor.ts   = MAX;
    475477        #if !defined(__CFA_NO_STATISTICS__)
    476                 this.cnt  = 0;
     478                this.l.cnt  = 0;
    477479        #endif
    478480
    479481        // We add a boat-load of assertions here because the anchor code is very fragile
    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   );
     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   );
    485487        /* paranoid */ verify( mock_head(this)->link.next == 0p );
    486488        /* paranoid */ verify( mock_head(this)->link.ts   == MAX );
    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 }
     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
    492496
    493497// Dtor is trivial
    494498void ^?{}( __intrusive_lane_t & this ) {
    495499        // Make sure the list is empty
    496         /* paranoid */ verify( this.anchor.next == 0p );
    497         /* paranoid */ verify( this.anchor.ts   == MAX );
    498         /* paranoid */ verify( mock_head(this)  == this.prev );
     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 );
    499503}
    500504
  • libcfa/src/concurrency/kernel/cluster.hfa

    r13d326ec r2af1943  
    3939        if (ts_next == ULLONG_MAX) return;
    4040        unsigned long long now = rdtscl();
    41         unsigned long long pma = __atomic_load_n(&tscs[ idx ].ma, __ATOMIC_RELAXED);
    42         __atomic_store_n(&tscs[ idx ].tv, ts_next, __ATOMIC_RELAXED);
    43         __atomic_store_n(&tscs[ idx ].ma, moving_average(now, ts_prev, pma), __ATOMIC_RELAXED);
     41        unsigned long long pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);
     42        __atomic_store_n(&tscs[ idx ].t.tv, ts_next, __ATOMIC_RELAXED);
     43        __atomic_store_n(&tscs[ idx ].t.ma, moving_average(now, ts_prev, pma), __ATOMIC_RELAXED);
    4444}
    4545
     
    6161                if(ptsc != ULLONG_MAX) {
    6262                        /* paranoid */ verify( start + i < count );
    63                         unsigned long long tsc = moving_average(ctsc, ptsc, tscs[start + i].ma);
     63                        unsigned long long tsc = moving_average(ctsc, ptsc, tscs[start + i].t.ma);
    6464                        if(tsc > max) max = tsc;
    6565                }
  • libcfa/src/concurrency/kernel/fwd.hfa

    r13d326ec r2af1943  
    3535extern "C" {
    3636        extern "Cforall" {
    37                 extern __attribute__((aligned(128))) thread_local struct KernelThreadData {
     37                extern __attribute__((aligned(64))) thread_local struct KernelThreadData {
    3838                        struct thread$          * volatile this_thread;
    3939                        struct processor        * volatile this_processor;
  • libcfa/src/concurrency/kernel/private.hfa

    r13d326ec r2af1943  
    8888#elif defined(CFA_HAVE_LINUX_RSEQ_H)
    8989        extern "Cforall" {
    90                 extern __attribute__((aligned(128))) thread_local volatile struct rseq __cfaabi_rseq;
     90                extern __attribute__((aligned(64))) thread_local volatile struct rseq __cfaabi_rseq;
    9191        }
    9292#else
  • libcfa/src/concurrency/kernel/startup.cfa

    r13d326ec r2af1943  
    152152#elif defined(CFA_HAVE_LINUX_RSEQ_H)
    153153        extern "Cforall" {
    154                 __attribute__((aligned(128))) thread_local volatile struct rseq __cfaabi_rseq @= {
     154                __attribute__((aligned(64))) thread_local volatile struct rseq __cfaabi_rseq @= {
    155155                        .cpu_id : RSEQ_CPU_ID_UNINITIALIZED,
    156156                };
Note: See TracChangeset for help on using the changeset viewer.