Changeset 0fc447c


Ignore:
Timestamp:
Jan 17, 2022, 2:25:00 PM (6 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
enum, forall-pointer-decay, master
Children:
25337e0, a77f25b
Parents:
a2a4566
Message:

Removed fast_lock, which doesn't seemed to have ever worked and isn't used in the first place

Files:
5 deleted
3 edited

Legend:

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

    ra2a4566 r0fc447c  
    2929#include "time_t.hfa"
    3030#include "time.hfa"
    31 
    32 //-----------------------------------------------------------------------------
    33 // Semaphores
    34 
    35 // '0-nary' semaphore
    36 // Similar to a counting semaphore except the value of one is never reached
    37 // as a consequence, a V() that would bring the value to 1 *spins* until
    38 // a P consumes it
    39 struct Semaphore0nary {
    40         __spinlock_t lock; // needed to protect
    41         mpsc_queue(thread$) queue;
    42 };
    43 
    44 static inline bool P(Semaphore0nary & this, thread$ * thrd) {
    45         /* paranoid */ verify(!thrd`next);
    46         /* paranoid */ verify(!(&(*thrd)`next));
    47 
    48         push(this.queue, thrd);
    49         return true;
    50 }
    51 
    52 static inline bool P(Semaphore0nary & this) {
    53     thread$ * thrd = active_thread();
    54     P(this, thrd);
    55     park();
    56     return true;
    57 }
    58 
    59 static inline thread$ * V(Semaphore0nary & this, bool doUnpark = true) {
    60         thread$ * next;
    61         lock(this.lock __cfaabi_dbg_ctx2);
    62                 for (;;) {
    63                         next = pop(this.queue);
    64                         if (next) break;
    65                         Pause();
    66                 }
    67         unlock(this.lock);
    68 
    69         if (doUnpark) unpark(next);
    70         return next;
    71 }
    72 
    73 // Wrapper used on top of any sempahore to avoid potential locking
    74 struct BinaryBenaphore {
    75         volatile ssize_t counter;
    76 };
    77 
    78 static inline {
    79         void ?{}(BinaryBenaphore & this) { this.counter = 0; }
    80         void ?{}(BinaryBenaphore & this, zero_t) { this.counter = 0; }
    81         void ?{}(BinaryBenaphore & this, one_t ) { this.counter = 1; }
    82 
    83         // returns true if no blocking needed
    84         bool P(BinaryBenaphore & this) {
    85                 return __atomic_fetch_sub(&this.counter, 1, __ATOMIC_SEQ_CST) > 0;
    86         }
    87 
    88         bool tryP(BinaryBenaphore & this) {
    89                 ssize_t c = this.counter;
    90                 /* paranoid */ verify( c > MIN );
    91                 return (c >= 1) && __atomic_compare_exchange_n(&this.counter, &c, c-1, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
    92         }
    93 
    94         // returns true if notify needed
    95         bool V(BinaryBenaphore & this) {
    96                 ssize_t c = 0;
    97                 for () {
    98                         /* paranoid */ verify( this.counter < MAX );
    99                         if (__atomic_compare_exchange_n(&this.counter, &c, c+1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    100                                 if (c == 0) return true;
    101                                 /* paranoid */ verify(c < 0);
    102                                 return false;
    103                         } else {
    104                                 if (c == 1) return true;
    105                                 /* paranoid */ verify(c < 1);
    106                                 Pause();
    107                         }
    108                 }
    109         }
    110 }
    111 
    112 // Binary Semaphore based on the BinaryBenaphore on top of the 0-nary Semaphore
    113 struct ThreadBenaphore {
    114         BinaryBenaphore ben;
    115         Semaphore0nary  sem;
    116 };
    117 
    118 static inline void ?{}(ThreadBenaphore & this) {}
    119 static inline void ?{}(ThreadBenaphore & this, zero_t) { (this.ben){ 0 }; }
    120 static inline void ?{}(ThreadBenaphore & this, one_t ) { (this.ben){ 1 }; }
    121 
    122 static inline bool P(ThreadBenaphore & this)              { return P(this.ben) ? false : P(this.sem); }
    123 static inline bool tryP(ThreadBenaphore & this)           { return tryP(this.ben); }
    124 static inline bool P(ThreadBenaphore & this, bool wait)   { return wait ? P(this) : tryP(this); }
    125 
    126 static inline thread$ * V(ThreadBenaphore & this, bool doUnpark = true) {
    127         if (V(this.ben)) return 0p;
    128         return V(this.sem, doUnpark);
    129 }
    13031
    13132//-----------------------------------------------------------------------------
     
    17172static inline void   on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    17273static inline void   on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    173 
    174 struct fast_lock {
    175         thread$ * volatile owner;
    176         ThreadBenaphore sem;
    177 };
    178 
    179 static inline void ?{}(fast_lock & this) __attribute__((deprecated("use linear_backoff_then_block_lock instead")));
    180 static inline void ?{}(fast_lock & this) { this.owner = 0p; }
    181 
    182 static inline bool $try_lock(fast_lock & this, thread$ * thrd) {
    183     thread$ * exp = 0p;
    184     return __atomic_compare_exchange_n(&this.owner, &exp, thrd, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
    185 }
    186 
    187 static inline void lock( fast_lock & this ) __attribute__((deprecated("use linear_backoff_then_block_lock instead"), artificial));
    188 static inline void lock( fast_lock & this ) {
    189         thread$ * thrd = active_thread();
    190         /* paranoid */verify(thrd != this.owner);
    191 
    192         for (;;) {
    193                 if ($try_lock(this, thrd)) return;
    194                 P(this.sem);
    195         }
    196 }
    197 
    198 static inline bool try_lock( fast_lock & this ) __attribute__((deprecated("use linear_backoff_then_block_lock instead"), artificial));
    199 static inline bool try_lock ( fast_lock & this ) {
    200         thread$ * thrd = active_thread();
    201         /* paranoid */ verify(thrd != this.owner);
    202         return $try_lock(this, thrd);
    203 }
    204 
    205 static inline thread$ * unlock( fast_lock & this ) __attribute__((deprecated("use linear_backoff_then_block_lock instead"), artificial));
    206 static inline thread$ * unlock( fast_lock & this ) {
    207         /* paranoid */ verify(active_thread() == this.owner);
    208 
    209         // open 'owner' before unlocking anyone
    210         // so new and unlocked threads don't park incorrectly.
    211         // This may require additional fencing on ARM.
    212         this.owner = 0p;
    213 
    214         return V(this.sem);
    215 }
    216 
    217 static inline size_t on_wait( fast_lock & this ) { unlock(this); return 0; }
    218 static inline void on_wakeup( fast_lock & this, size_t ) { lock(this); }
    219 static inline void on_notify( fast_lock &, struct thread$ * t ) { unpark(t); }
    22074
    22175struct mcs_node {
  • tests/unified_locking/.expect/locks.txt

    ra2a4566 r0fc447c  
    1111Start Test 6: owner lock and condition variable 3 wait/notify all
    1212Done Test 6
    13 Start Test 7: fast lock and condition variable single wait/notify
     13Start Test 7: linear backoff lock and condition variable single wait/notify
    1414Done Test 7
    15 Start Test 8: fast lock and condition variable 3 wait/notify all
     15Start Test 8: linear backoff lock and condition variable 3 wait/notify all
    1616Done Test 8
    17 Start Test 9: linear backoff lock and condition variable single wait/notify
     17Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify
    1818Done Test 9
    19 Start Test 10: linear backoff lock and condition variable 3 wait/notify all
     19Start Test 10: owner lock and condition variable multiple acquire and wait/notify
    2020Done Test 10
    21 Start Test 11: multi acquisiton lock and condition variable multiple acquire and wait/notify
     21Start Test 11: no lock condition variable wait/notify
    2222Done Test 11
    23 Start Test 12: owner lock and condition variable multiple acquire and wait/notify
     23Start Test 12: locked condition variable wait/notify with front()
    2424Done Test 12
    25 Start Test 13: no lock condition variable wait/notify
    26 Done Test 13
    27 Start Test 14: locked condition variable wait/notify with front()
    28 Done Test 14
  • tests/unified_locking/locks.cfa

    ra2a4566 r0fc447c  
    1515condition_variable( owner_lock ) c_o;
    1616
    17 fast_lock f;
    18 condition_variable( fast_lock ) c_f;
    19 
    2017linear_backoff_then_block_lock l;
    2118condition_variable( linear_backoff_then_block_lock ) c_l;
     
    7471                }
    7572                unlock(s);
    76         }
    77 }
    78 
    79 thread T_C_F_WS1 {};
    80 
    81 void main( T_C_F_WS1 & this ) {
    82         for (unsigned int i = 0; i < num_times; i++) {
    83                 lock(f);
    84                 if(empty(c_f) && i != num_times - 1) {
    85                         wait(c_f,f);
    86                 }else{
    87                         notify_one(c_f);
    88                 }
    89                 unlock(f);
    90         }
    91 }
    92 
    93 thread T_C_F_WB1 {};
    94 
    95 void main( T_C_F_WB1 & this ) {
    96         for (unsigned int i = 0; i < num_times; i++) {
    97                 lock(f);
    98                 if(counter(c_f) == 3 || i == num_times - 1) {
    99                         notify_all(c_f);
    100                 }else{
    101                         wait(c_f,f);
    102                 }
    103                 unlock(f);
    10473        }
    10574}
     
    317286        printf("Done Test 6\n");
    318287
    319         printf("Start Test 7: fast lock and condition variable single wait/notify\n");
    320         {
    321                 T_C_F_WS1 t1[2];
     288        printf("Start Test 7: linear backoff lock and condition variable single wait/notify\n");
     289        {
     290                T_C_L_WS1 t1[2];
    322291        }
    323292        printf("Done Test 7\n");
    324293
    325         printf("Start Test 8: fast lock and condition variable 3 wait/notify all\n");
    326         {
    327                 T_C_F_WB1 t1[4];
     294        printf("Start Test 8: linear backoff lock and condition variable 3 wait/notify all\n");
     295        {
     296                T_C_L_WB1 t1[4];
    328297        }
    329298        printf("Done Test 8\n");
    330299
    331         printf("Start Test 9: linear backoff lock and condition variable single wait/notify\n");
    332         {
    333                 T_C_L_WS1 t1[2];
     300        printf("Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify\n");
     301        {
     302                T_C_M_WS2 t1[2];
    334303        }
    335304        printf("Done Test 9\n");
    336305
    337         printf("Start Test 10: linear backoff lock and condition variable 3 wait/notify all\n");
    338         {
    339                 T_C_L_WB1 t1[4];
     306        printf("Start Test 10: owner lock and condition variable multiple acquire and wait/notify\n");
     307        {
     308                T_C_O_WS2 t1[2];
    340309        }
    341310        printf("Done Test 10\n");
    342311
    343         printf("Start Test 11: multi acquisiton lock and condition variable multiple acquire and wait/notify\n");
    344         {
    345                 T_C_M_WS2 t1[2];
    346         }
    347         printf("Done Test 11\n");
    348 
    349         printf("Start Test 12: owner lock and condition variable multiple acquire and wait/notify\n");
    350         {
    351                 T_C_O_WS2 t1[2];
    352         }
    353         printf("Done Test 12\n");
    354 
    355         printf("Start Test 13: no lock condition variable wait/notify\n");
     312        printf("Start Test 11: no lock condition variable wait/notify\n");
    356313        {
    357314                T_C_NLW t1;
    358315                T_C_NLS t2;
    359316        }
    360         printf("Done Test 13\n");
    361 
    362         printf("Start Test 14: locked condition variable wait/notify with front()\n");
     317        printf("Done Test 11\n");
     318
     319        printf("Start Test 12: locked condition variable wait/notify with front()\n");
    363320        {
    364321                T_C_S_WNF t1[2];
    365322        }
    366         printf("Done Test 14\n");
    367 }
     323        printf("Done Test 12\n");
     324}
Note: See TracChangeset for help on using the changeset viewer.