Ignore:
File:
1 edited

Legend:

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

    rbeeff61e rf5f2768  
    7979        // lock is held by some other thread
    8080        if ( owner != 0p && owner != thrd ) {
    81         select_node node;
    82                 insert_last( blocked_threads, node );
     81                insert_last( blocked_threads, *thrd );
    8382                wait_count++;
    8483                unlock( lock );
    8584                park( );
    86         return;
    87         } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread
     85        }
     86        // multi acquisition lock is held by current thread
     87        else if ( owner == thrd && multi_acquisition ) {
    8888                recursion_count++;
    89         } else {  // lock isn't held
     89                unlock( lock );
     90        }
     91        // lock isn't held
     92        else {
    9093                owner = thrd;
    9194                recursion_count = 1;
    92         }
    93     unlock( lock );
     95                unlock( lock );
     96        }
    9497}
    9598
     
    114117}
    115118
    116 // static void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
    117 //      thread$ * t = &try_pop_front( blocked_threads );
    118 //      owner = t;
    119 //      recursion_count = ( t ? 1 : 0 );
    120 //      if ( t ) wait_count--;
    121 //      unpark( t );
    122 // }
    123 
    124 static inline void pop_node( blocking_lock & this ) with( this ) {
    125     __handle_waituntil_OR( blocked_threads );
    126     select_node * node = &try_pop_front( blocked_threads );
    127     if ( node ) {
    128         wait_count--;
    129         owner = node->blocked_thread;
    130         recursion_count = 1;
    131         // if ( !node->clause_status || __make_select_node_available( *node ) ) unpark( node->blocked_thread );
    132         wake_one( blocked_threads, *node );
    133     } else {
    134         owner = 0p;
    135         recursion_count = 0;
    136     }
     119static void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
     120        thread$ * t = &try_pop_front( blocked_threads );
     121        owner = t;
     122        recursion_count = ( t ? 1 : 0 );
     123        if ( t ) wait_count--;
     124        unpark( t );
    137125}
    138126
     
    146134        recursion_count--;
    147135        if ( recursion_count == 0 ) {
    148                 pop_node( this );
     136                pop_and_set_new_owner( this );
    149137        }
    150138        unlock( lock );
     
    159147        // lock held
    160148        if ( owner != 0p ) {
    161                 insert_last( blocked_threads, *(select_node *)t->link_node );
     149                insert_last( blocked_threads, *t );
    162150                wait_count++;
     151                unlock( lock );
    163152        }
    164153        // lock not held
     
    167156                recursion_count = 1;
    168157                unpark( t );
    169         }
    170     unlock( lock );
     158                unlock( lock );
     159        }
    171160}
    172161
     
    178167        size_t ret = recursion_count;
    179168
    180         pop_node( this );
    181 
    182     select_node node;
    183     active_thread()->link_node = (void *)&node;
     169        pop_and_set_new_owner( this );
    184170        unlock( lock );
    185 
    186     park();
    187 
    188171        return ret;
    189172}
     
    192175        recursion_count = recursion;
    193176}
    194 
    195 // waituntil() support
    196 bool register_select( blocking_lock & this, select_node & node ) with(this) {
    197     lock( lock __cfaabi_dbg_ctx2 );
    198         thread$ * thrd = active_thread();
    199 
    200         // single acquisition lock is held by current thread
    201         /* paranoid */ verifyf( owner != thrd || multi_acquisition, "Single acquisition lock holder (%p) attempted to reacquire the lock %p resulting in a deadlock.", owner, &this );
    202 
    203     if ( !node.park_counter && ( (owner == thrd && multi_acquisition) || owner == 0p ) ) { // OR special case
    204         if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
    205            unlock( lock );
    206            return false;
    207         }
    208     }
    209 
    210         // lock is held by some other thread
    211         if ( owner != 0p && owner != thrd ) {
    212                 insert_last( blocked_threads, node );
    213                 wait_count++;
    214                 unlock( lock );
    215         return false;
    216         } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread
    217                 recursion_count++;
    218         } else {  // lock isn't held
    219                 owner = thrd;
    220                 recursion_count = 1;
    221         }
    222 
    223     if ( node.park_counter ) __make_select_node_available( node );
    224     unlock( lock );
    225     return true;
    226 }
    227 
    228 bool unregister_select( blocking_lock & this, select_node & node ) with(this) {
    229     lock( lock __cfaabi_dbg_ctx2 );
    230     if ( node`isListed ) {
    231         remove( node );
    232         wait_count--;
    233         unlock( lock );
    234         return false;
    235     }
    236    
    237     if ( owner == active_thread() ) {
    238         /* paranoid */ verifyf( recursion_count == 1 || multi_acquisition, "Thread %p attempted to unlock owner lock %p in waituntil unregister, which is not recursive but has a recursive count of %zu", active_thread(), &this, recursion_count );
    239         // if recursion count is zero release lock and set new owner if one is waiting
    240         recursion_count--;
    241         if ( recursion_count == 0 ) {
    242             pop_node( this );
    243         }
    244     }
    245         unlock( lock );
    246     return false;
    247 }
    248 
    249 bool on_selected( blocking_lock & this, select_node & node ) { return true; }
    250177
    251178//-----------------------------------------------------------------------------
     
    384311        int counter( condition_variable(L) & this ) with(this) { return count; }
    385312
    386         static void enqueue_thread( condition_variable(L) & this, info_thread(L) * i ) with(this) {
     313        static size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
    387314                // add info_thread to waiting queue
    388315                insert_last( blocked_threads, *i );
    389316                count++;
    390                 // size_t recursion_count = 0;
    391                 // if (i->lock) {
    392                 //      // if lock was passed get recursion count to reset to after waking thread
    393                 //      recursion_count = on_wait( *i->lock );
    394                 // }
    395                 // return recursion_count;
    396         }
    397 
    398     static size_t block_and_get_recursion( info_thread(L) & i ) {
    399         size_t recursion_count = 0;
    400                 if ( i.lock ) {
     317                size_t recursion_count = 0;
     318                if (i->lock) {
    401319                        // if lock was passed get recursion count to reset to after waking thread
    402                         recursion_count = on_wait( *i.lock ); // this call blocks
    403                 } else park( );
    404         return recursion_count;
    405     }
     320                        recursion_count = on_wait( *i->lock );
     321                }
     322                return recursion_count;
     323        }
    406324
    407325        // helper for wait()'s' with no timeout
    408326        static void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
    409327                lock( lock __cfaabi_dbg_ctx2 );
    410         enqueue_thread( this, &i );
    411                 // size_t recursion_count = queue_and_get_recursion( this, &i );
     328                size_t recursion_count = queue_and_get_recursion(this, &i);
    412329                unlock( lock );
    413330
    414331                // blocks here
    415         size_t recursion_count = block_and_get_recursion( i );
    416                 // park( );
     332                park( );
    417333
    418334                // resets recursion count here after waking
    419                 if ( i.lock ) on_wakeup( *i.lock, recursion_count );
     335                if (i.lock) on_wakeup(*i.lock, recursion_count);
    420336        }
    421337
     
    427343        static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
    428344                lock( lock __cfaabi_dbg_ctx2 );
    429         enqueue_thread( this, &info );
    430                 // size_t recursion_count = queue_and_get_recursion( this, &info );
     345                size_t recursion_count = queue_and_get_recursion(this, &info);
    431346                alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info };
    432347                unlock( lock );
     
    436351
    437352                // blocks here
    438         size_t recursion_count = block_and_get_recursion( info );
    439                 // park();
     353                park();
    440354
    441355                // unregisters alarm so it doesn't go off if this happens first
     
    443357
    444358                // resets recursion count here after waking
    445                 if ( info.lock ) on_wakeup( *info.lock, recursion_count );
     359                if (info.lock) on_wakeup(*info.lock, recursion_count);
    446360        }
    447361
     
    503417                info_thread( L ) i = { active_thread(), info, &l };
    504418                insert_last( blocked_threads, i );
    505                 size_t recursion_count = on_wait( *i.lock ); // blocks here
    506                 // park( );
     419                size_t recursion_count = on_wait( *i.lock );
     420                park( );
    507421                on_wakeup(*i.lock, recursion_count);
    508422        }
     
    545459        bool empty ( pthread_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty; }
    546460
    547         // static size_t queue_and_get_recursion( pthread_cond_var(L) & this, info_thread(L) * i ) with(this) {
    548         //      // add info_thread to waiting queue
    549         //      insert_last( blocked_threads, *i );
    550         //      size_t recursion_count = 0;
    551         //      recursion_count = on_wait( *i->lock );
    552         //      return recursion_count;
    553         // }
    554 
     461        static size_t queue_and_get_recursion( pthread_cond_var(L) & this, info_thread(L) * i ) with(this) {
     462                // add info_thread to waiting queue
     463                insert_last( blocked_threads, *i );
     464                size_t recursion_count = 0;
     465                recursion_count = on_wait( *i->lock );
     466                return recursion_count;
     467        }
    555468       
    556469        static void queue_info_thread_timeout( pthread_cond_var(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
    557470                lock( lock __cfaabi_dbg_ctx2 );
    558                 // size_t recursion_count = queue_and_get_recursion(this, &info);
    559         insert_last( blocked_threads, info );
     471                size_t recursion_count = queue_and_get_recursion(this, &info);
    560472                pthread_alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info };
    561473                unlock( lock );
     
    565477
    566478                // blocks here
    567         size_t recursion_count = block_and_get_recursion( info );
    568                 // park();
     479                park();
    569480
    570481                // unregisters alarm so it doesn't go off if this happens first
     
    572483
    573484                // resets recursion count here after waking
    574                 if ( info.lock ) on_wakeup( *info.lock, recursion_count );
     485                if (info.lock) on_wakeup(*info.lock, recursion_count);
    575486        }
    576487
     
    582493                lock( lock __cfaabi_dbg_ctx2 );
    583494                info_thread( L ) i = { active_thread(), info, &l };
    584         insert_last( blocked_threads, i );
    585                 // size_t recursion_count = queue_and_get_recursion( this, &i );
    586                 unlock( lock );
    587 
    588         // blocks here
    589                 size_t recursion_count = block_and_get_recursion( i );
    590                 // park();
    591                 on_wakeup( *i.lock, recursion_count );
     495                size_t recursion_count = queue_and_get_recursion(this, &i);
     496                unlock( lock );
     497                park( );
     498                on_wakeup(*i.lock, recursion_count);
    592499        }
    593500
Note: See TracChangeset for help on using the changeset viewer.