Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/locks.hfa

    r8f5576d5 rc7c178b  
    3939};
    4040
    41 static inline bool P(Semaphore0nary & this, $thread * thrd) __attribute__((artificial));
    4241static inline bool P(Semaphore0nary & this, $thread * thrd) {
    4342        /* paranoid */ verify(!(thrd->seqable.next));
     
    4847}
    4948
    50 static inline bool P(Semaphore0nary & this) __attribute__((artificial));
    5149static inline bool P(Semaphore0nary & this) {
    5250    $thread * thrd = active_thread();
     
    5654}
    5755
    58 static inline $thread * V(Semaphore0nary & this, const bool doUnpark = true) __attribute__((artificial));
    5956static inline $thread * V(Semaphore0nary & this, const bool doUnpark = true) {
    6057        $thread * next;
     
    8279
    8380        // returns true if no blocking needed
    84         bool P(BinaryBenaphore & this) { return __atomic_fetch_sub(&this.counter, 1, __ATOMIC_SEQ_CST) > 0; }
     81        bool P(BinaryBenaphore & this) {
     82                return __atomic_fetch_sub(&this.counter, 1, __ATOMIC_SEQ_CST) > 0;
     83        }
     84
    8585        bool tryP(BinaryBenaphore & this) {
    8686                ssize_t c = this.counter;
     
    115115static inline void ?{}(ThreadBenaphore & this, one_t ) { (this.ben){ 1 }; }
    116116
    117 static inline bool P(ThreadBenaphore & this)              { return /* P(this.ben) ? false : */ P(this.sem); }
    118 static inline bool P(ThreadBenaphore & this, $thread * t) { return /* P(this.ben) ? false : */ P(this.sem, t ); }
     117static inline bool P(ThreadBenaphore & this)              { return P(this.ben) ? false : P(this.sem); }
    119118static inline bool tryP(ThreadBenaphore & this)           { return tryP(this.ben); }
    120119static inline bool P(ThreadBenaphore & this, bool wait)   { return wait ? P(this) : tryP(this); }
    121120
    122121static inline $thread * V(ThreadBenaphore & this, const bool doUnpark = true) {
    123         // if (V(this.ben)) return 0p;
     122        if (V(this.ben)) return 0p;
    124123        return V(this.sem, doUnpark);
    125124}
     
    138137bool   V (semaphore & this);
    139138bool   V (semaphore & this, unsigned count);
     139$thread * V (semaphore & this, bool );
    140140
    141141//----------
     
    146146static inline void  ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
    147147static inline void ^?{}( single_acquisition_lock & this ) {}
    148 static inline void   lock      ( single_acquisition_lock & this ) { lock    ( (blocking_lock &)this ); }
    149 static inline bool   try_lock  ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); }
    150 static inline void   unlock    ( single_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
    151 static inline void   on_wait   ( single_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); }
    152 static inline void   on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    153 static inline void   set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
    154 static inline size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
     148static inline void   lock     ( single_acquisition_lock & this ) { lock    ( (blocking_lock &)this ); }
     149static inline bool   try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); }
     150static inline void   unlock   ( single_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
     151static inline size_t on_wait  ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); }
     152static inline void   on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
     153static inline void   on_notify( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    155154
    156155//----------
     
    164163static inline bool   try_lock ( owner_lock & this ) { return try_lock( (blocking_lock &)this ); }
    165164static inline void   unlock   ( owner_lock & this ) { unlock  ( (blocking_lock &)this ); }
    166 static inline void   on_wait  ( owner_lock & this ) { on_wait ( (blocking_lock &)this ); }
     165static inline size_t on_wait  ( owner_lock & this ) { return on_wait ( (blocking_lock &)this ); }
     166static inline void   on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    167167static inline void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    168 static inline void   set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
    169 static inline size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
    170168
    171169struct fast_lock {
     
    179177}
    180178
    181 static inline void $lock(fast_lock & this, $thread * thrd) {
    182         /* paranoid */verify(thrd != this.owner);
    183 
    184         for (;;) {
    185                 if ($try_lock(this, thrd)) return;
    186                 P(this.sem, thrd);
    187         }
    188 }
    189 
     179static inline void lock( fast_lock & this ) __attribute__((artificial));
    190180static inline void lock( fast_lock & this ) {
    191181        $thread * thrd = active_thread();
     
    198188}
    199189
    200 static inline void try_lock ( fast_lock & this ) {
     190static inline bool try_lock( fast_lock & this ) __attribute__((artificial));
     191static inline bool try_lock ( fast_lock & this ) {
    201192        $thread * thrd = active_thread();
    202193        /* paranoid */ verify(thrd != this.owner);
     
    204195}
    205196
    206 static inline void unlock( fast_lock & this ) {
     197static inline $thread * unlock( fast_lock & this ) __attribute__((artificial));
     198static inline $thread * unlock( fast_lock & this ) {
    207199        $thread * thrd = active_thread();
    208200        /* paranoid */ verify(thrd == this.owner);
    209         $thread * next = V(this.sem, false); // implicit fence
    210         // open 'owner' only after fence
     201
     202        // open 'owner' before unlocking anyone
     203        // so new and unlocked threads don't park incorrectly.
     204        // This may require additional fencing on ARM.
    211205        this.owner = 0p;
    212206
    213         // Unpark the next person (can be 0p, unpark handles it)
    214         unpark(next);
    215 }
    216 
    217 static inline void on_wait( fast_lock & this ) {
    218         unlock(this);
    219         #warning this is broken
    220 }
    221 
    222 static inline void on_notify( fast_lock & this, struct $thread * t ) {
    223         $lock(this, t);
    224         #warning this is broken
    225 }
    226 
    227 static inline void   set_recursion_count( fast_lock & this, size_t recursion ) {}
    228 static inline size_t get_recursion_count( fast_lock & this ) { return 0; }
     207        return V(this.sem, true);
     208}
     209
     210static inline size_t on_wait( fast_lock & this ) { unlock(this); return 0; }
     211static inline void on_wakeup( fast_lock & this, size_t ) { lock(this); }
     212static inline void on_notify( fast_lock &, struct $thread * t ) { unpark(t); }
    229213
    230214struct mcs_node {
     
    260244
    261245        // For synchronization locks to use when releasing
    262         void on_wait( L & );
    263 
    264         // to get recursion count for cond lock to reset after waking
    265         size_t get_recursion_count( L & );
     246        size_t on_wait( L & );
    266247
    267248        // to set recursion count after getting signalled;
    268         void set_recursion_count( L &, size_t recursion );
     249        void on_wakeup( L &, size_t recursion );
    269250};
    270251
Note: See TracChangeset for help on using the changeset viewer.