Changeset e50d9cb8 for libcfa/src


Ignore:
Timestamp:
Nov 1, 2022, 10:06:40 PM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
7cf8006
Parents:
0bdfcc3 (diff), 03c56f6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r0bdfcc3 re50d9cb8  
    111111        concurrency/invoke.h \
    112112        concurrency/future.hfa \
     113        concurrency/once.hfa \
    113114        concurrency/kernel/fwd.hfa \
    114115        concurrency/mutex_stmt.hfa
  • libcfa/src/bits/defs.hfa

    r0bdfcc3 re50d9cb8  
    3131#define __cfa_anonymous_object(x) inline struct x
    3232#define __cfa_dlink1(x) dlink(x)
     33#define __cfa_dlink2(x, name) inline struct name { inline dlink(x); }
    3334#else
    3435#define __cfa_anonymous_object(x) struct x __cfa_anonymous_object
    3536#define __cfa_dlink1(x) struct { struct x * next; struct x * back; }
     37#define __cfa_dlink2(x, name) struct { struct x * next; struct x * back; } __dlink ## name
    3638#endif
    3739
  • libcfa/src/concurrency/invoke.h

    r0bdfcc3 re50d9cb8  
    195195                struct __monitor_group_t monitors;
    196196
    197                 // used to put threads on dlist data structure
     197                // intrusive link fields, used for locks, monitors and any user defined data structure
     198                // default link fields for dlist
    198199                __cfa_dlink1(thread$) user_link;
    199200
    200                 struct {
    201                         struct thread$ * next;
    202                         struct thread$ * prev;
    203                 } node;
     201                // secondary intrusive link fields, used for global cluster list
     202                // default link fields for dlist
     203                __cfa_dlink2(thread$, cltr_link);
    204204
    205205                // used to store state between clh lock/unlock
     
    230230        #ifdef __cforall
    231231        extern "Cforall" {
     232                static inline thread$ * volatile & ?`next ( thread$ * this ) {
     233                        return this->user_link.next;
     234                }
    232235
    233236                static inline thread$ *& get_next( thread$ & this ) __attribute__((const)) {
    234237                        return this.user_link.next;
    235                 }
    236 
    237                 static inline [thread$ *&, thread$ *& ] __get( thread$ & this ) __attribute__((const)) {
    238                         return this.node.[next, prev];
    239238                }
    240239
     
    244243                        return result;
    245244                }
     245
     246                P9_EMBEDDED(thread$, thread$.cltr_link)
     247                P9_EMBEDDED(thread$.cltr_link, dlink(thread$))
    246248
    247249                static inline void ?{}(__monitor_group_t & this) {
  • libcfa/src/concurrency/kernel.hfa

    r0bdfcc3 re50d9cb8  
    256256        // List of threads
    257257        __spinlock_t thread_list_lock;
    258         __dllist_t(struct thread$) threads;
     258        dlist(struct thread$, thread$.cltr_link) threads;
    259259        unsigned int nthreads;
    260260
  • libcfa/src/concurrency/kernel/startup.cfa

    r0bdfcc3 re50d9cb8  
    535535        #endif
    536536
    537         node.next = 0p;
    538         node.prev = 0p;
    539537        doregister(curr_cluster, this);
    540538
     
    659657        #endif
    660658
    661         threads{ __get };
     659        threads{};
    662660
    663661        io.arbiter = create();
     
    739737        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    740738        cltr->nthreads += 1;
    741         push_front(cltr->threads, thrd);
     739        insert_first(cltr->threads, thrd);
    742740        unlock    (cltr->thread_list_lock);
    743741}
     
    745743void unregister( cluster * cltr, thread$ & thrd ) {
    746744        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    747         remove(cltr->threads, thrd );
    748         cltr->nthreads -= 1;
     745        {
     746                tytagref( dlink(thread$), dlink(thread$) ) ?`inner( thread$ & this ) = void;
     747                with( DLINK_VIA( thread$, thread$.cltr_link ) )
     748                        remove( thrd );
     749                cltr->nthreads -= 1;
     750        }
    749751        unlock(cltr->thread_list_lock);
    750752}
  • libcfa/src/concurrency/thread.cfa

    r0bdfcc3 re50d9cb8  
    5454        #endif
    5555
    56         node.next = 0p;
    57         node.prev = 0p;
    58 
    5956        clh_node = malloc( );
    6057        *clh_node = false;
  • libcfa/src/containers/lockfree.hfa

    r0bdfcc3 re50d9cb8  
    142142
    143143        static inline void ?{}(poison_list(T) & this) { this.head = 0p; }
     144        static inline bool is_poisoned( const poison_list(T) & this ) { return 1p == this.head; }
    144145
    145146        static inline forall(| { T * volatile & ?`next ( T * ); })
     
    147148                // Adds an element to the list
    148149                // Multi-Thread Safe, Lock-Free
    149                 T * push(poison_list(T) & this, T * elem) __attribute__((artificial));
    150                 T * push(poison_list(T) & this, T * elem) {
     150                bool push(poison_list(T) & this, T * elem) __attribute__((artificial));
     151                bool push(poison_list(T) & this, T * elem) {
    151152                        /* paranoid */ verify(0p == (elem`next));
    152153                        __atomic_store_n( &elem`next, (T*)1p, __ATOMIC_RELAXED );
     
    156157                        for() {
    157158                                // check if it's poisoned
    158                                 if(expected == 1p) return 0p;
     159                                if(expected == 1p) return false;
    159160
    160161                                // try to CAS the elem in
     
    162163                                        // We managed to exchange in, we are done
    163164
    164                                         // We should never succeed the CAS if it's poisonned.
    165                                         /* paranoid */ verify( expected != 1p );
     165                                        // We should never succeed the CAS if it's poisonned and the elem should be 1p.
     166                                        /* paranoid */ verify( expected  != 1p );
     167                                        /* paranoid */ verify( elem`next == 1p );
    166168
    167169                                        // If we aren't the first, we need to tell the person before us
    168170                                        // No need to
    169171                                        elem`next = expected;
    170                                         return expected;
     172                                        return true;
    171173                                }
    172174                        }
     
    190192                T * poison(poison_list(T) & this) {
    191193                        T * ret = __atomic_exchange_n( &this.head, (T*)1p, __ATOMIC_SEQ_CST );
    192                         /* paranoid */ verify( ret != (T*)1p );
     194                        /* paranoid */ verifyf( ret != (T*)1p, "Poison list %p poisoned more than once!", &this );
    193195                        return ret;
    194196                }
Note: See TracChangeset for help on using the changeset viewer.