Ignore:
Timestamp:
Dec 22, 2020, 12:50:46 PM (4 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
26a249c, 302ef2a
Parents:
fe97de26
Message:

cleaned up locks code and added comments

File:
1 edited

Legend:

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

    rfe97de26 r797a193  
    11#include "locks.hfa"
    22#include "kernel_private.hfa"
    3 #include <stdlib.h>
    4 #include <stdio.h>
    53
    64#include <kernel.hfa>
    75#include <stdlib.hfa>
    8 #include <thread.hfa>
    96
    107///////////////////////////////////////////////////////////////////
     
    6158void lock( blocking_lock & this ) with( this ) {
    6259        lock( lock __cfaabi_dbg_ctx2 );
    63         if ( owner == active_thread() && !multi_acquisition) {
     60        if ( owner == active_thread() && !multi_acquisition) { // single acquisition lock is held by current thread
    6461                abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock.");
    65         } else if ( owner != 0p && owner != active_thread() ) {
     62        } else if ( owner != 0p && owner != active_thread() ) { // lock is held by some other thread
    6663                addTail( blocked_threads, *active_thread() );
    6764                wait_count++;
    6865                unlock( lock );
    6966                park( );
    70         } else if ( owner == active_thread() && multi_acquisition ) {
     67        } else if ( owner == active_thread() && multi_acquisition ) { // multi acquisition lock is held by current thread
    7168                recursion_count++;
    7269                unlock( lock );
    73         } else {
     70        } else { // lock isn't held
    7471                owner = active_thread();
    7572                recursion_count = 1;
     
    8178        bool ret = false;
    8279        lock( lock __cfaabi_dbg_ctx2 );
    83         if ( owner == 0p ) {
     80        if ( owner == 0p ) { // lock isn't held
    8481                owner = active_thread();
    8582                recursion_count = 1;
    8683                ret = true;
    87         } else if ( owner == active_thread() && multi_acquisition ) {
     84        } else if ( owner == active_thread() && multi_acquisition ) { // multi acquisition lock is held by current thread
    8885                recursion_count++;
    8986                ret = true;
     
    9491
    9592void unlock_error_check( blocking_lock & this ) with( this ) {
    96         if ( owner == 0p ){ // no owner implies lock isn't held
     93        if ( owner == 0p ){ // lock isn't held
    9794                abort( "There was an attempt to release a lock that isn't held" );
    9895        } else if ( strict_owner && owner != active_thread() ) {
     
    113110        unlock_error_check( this );
    114111        recursion_count--;
    115         if ( recursion_count == 0 ) {
     112        if ( recursion_count == 0 ) { // if recursion count is zero release lock and set new owner if one is waiting
    116113                pop_and_set_new_owner( this );
    117114        }
     
    131128}
    132129
    133 void add_( blocking_lock & this, $thread * t ) with( this ) {
     130void on_notify( blocking_lock & this, $thread * t ) with( this ) {
    134131    lock( lock __cfaabi_dbg_ctx2 );
    135         if ( owner != 0p ) {
     132        if ( owner != 0p ) { // lock held
    136133                addTail( blocked_threads, *t );
    137134                wait_count++;
    138135                unlock( lock );
    139         } else {
     136        } else {        // lock not held
    140137                owner = t;
    141138                recursion_count = 1;
     
    145142}
    146143
    147 void remove_( blocking_lock & this ) with( this ) {
     144void on_wait( blocking_lock & this ) with( this ) {
    148145    lock( lock __cfaabi_dbg_ctx2 );
    149146        unlock_error_check( this );
     
    156153///////////////////////////////////////////////////////////////////
    157154
    158 // This is temporary until an inheritance bug is fixed
     155// These routines are temporary until an inheritance bug is fixed
    159156
    160157void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
    161158void unlock( single_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
    162 void add_( single_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
    163 void remove_( single_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
     159void on_notify( single_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
     160void on_wait( single_acquisition_lock & this ){ on_wait( (blocking_lock &)this ); }
    164161void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    165162size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     
    167164void lock( owner_lock & this ){ lock( (blocking_lock &)this ); }
    168165void unlock( owner_lock & this ){ unlock( (blocking_lock &)this ); }
    169 void add_( owner_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
    170 void remove_( owner_lock & this ){ remove_( (blocking_lock &)this ); }
     166void on_notify( owner_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
     167void on_wait( owner_lock & this ){ on_wait( (blocking_lock &)this ); }
    171168void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    172169size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     
    174171void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
    175172void unlock( multiple_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
    176 void add_( multiple_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
    177 void remove_( multiple_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
     173void on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
     174void on_wait( multiple_acquisition_lock & this ){ on_wait( (blocking_lock &)this ); }
    178175void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    179176size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     
    188185        // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
    189186            lock( cond->lock __cfaabi_dbg_ctx2 );
    190             if ( listed(i) ) {                  // is thread on queue
     187
     188            // this check is necessary to avoid a race condition since this timeout handler
     189            //  may still be called after a thread has been removed from the queue but
     190            //  before the alarm is unregistered
     191            if ( listed(i) ) {                                                  // is thread on queue
    191192                i->signalled = false;
    192                 cond->last_thread = i;          // REMOVE THIS AFTER DEBUG
    193                         remove( cond->blocked_threads, *i );             //remove this thread O(1)
     193                        remove( cond->blocked_threads, *i );    // remove this thread O(1)
    194194                        cond->count--;
    195                         if( !i->lock ) {
    196                                 unpark( i->t );
     195                        if( i->lock ) {
     196                                on_notify(*i->lock, i->t);                      // call lock's on_notify if a lock was passed
    197197                } else {
    198                         add_(*i->lock, i->t);                   // call lock's add_
     198                        unpark( i->t );                                         // otherwise wake thread
    199199                }
    200200            }
     
    202202        }
    203203
     204        // this casts the alarm node to our wrapped type since we used type erasure
    204205        void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
    205206
     
    208209                this.blocked_threads{};
    209210                this.count = 0;
    210                 this.last_thread = 0p; // REMOVE AFTER DEBUG
    211211        }
    212212
     
    224224                        count--;
    225225                        if (popped.lock) {
    226                                 add_(*popped.lock, popped.t);
     226                                on_notify(*popped.lock, popped.t); // if lock passed call on_notify
    227227                        } else {
    228                                 unpark(popped.t);
     228                                unpark(popped.t); // otherwise wake thread
    229229                        }
    230230                }
     
    258258
    259259        size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
    260                 addTail( blocked_threads, *i );
     260                addTail( blocked_threads, *i ); // add info_thread to waiting queue
    261261                count++;
    262262                size_t recursion_count = 0;
    263                 if (i->lock) {
     263                if (i->lock) { // if lock was passed get recursion count to reset to after waking thread
    264264                        recursion_count = get_recursion_count(*i->lock);
    265                         remove_( *i->lock );
     265                        on_wait( *i->lock );
    266266                }
    267267                return recursion_count;
     
    287287                unlock( lock );
    288288                park();
    289                 unregister_self( &node_wrap.alarm_node );
    290                 if (info.lock) set_recursion_count(*info.lock, recursion_count);
     289                unregister_self( &node_wrap.alarm_node ); // unregisters alarm so it doesn't go off if this happens first
     290                if (info.lock) set_recursion_count(*info.lock, recursion_count); // resets recursion count here after waking
    291291        }
    292292
Note: See TracChangeset for help on using the changeset viewer.