Ignore:
File:
1 edited

Legend:

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

    rc18bf9e r305aaef  
    2424#include <stdlib.hfa>
    2525
    26 #pragma GCC visibility push(default)
    27 
    2826//-----------------------------------------------------------------------------
    2927// info_thread
     
    118116}
    119117
    120 static void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
     118void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
    121119        thread$ * t = &try_pop_front( blocked_threads );
    122120        owner = t;
     
    176174        recursion_count = recursion;
    177175}
     176
     177//-----------------------------------------------------------------------------
     178// simple_owner_lock
     179
     180static inline void lock(simple_owner_lock & this) with(this) {
     181        if (owner == active_thread()) {
     182                recursion_count++;
     183                return;
     184        }
     185        lock( lock __cfaabi_dbg_ctx2 );
     186
     187        if (owner != 0p) {
     188                insert_last( blocked_threads, *active_thread() );
     189                unlock( lock );
     190                park( );
     191                return;
     192        }
     193        owner = active_thread();
     194        recursion_count = 1;
     195        unlock( lock );
     196}
     197
     198void pop_and_set_new_owner( simple_owner_lock & this ) with( this ) {
     199        thread$ * t = &try_pop_front( blocked_threads );
     200        owner = t;
     201        recursion_count = ( t ? 1 : 0 );
     202        unpark( t );
     203}
     204
     205static inline void unlock(simple_owner_lock & this) with(this) {
     206        lock( lock __cfaabi_dbg_ctx2 );
     207        /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
     208        /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
     209        // if recursion count is zero release lock and set new owner if one is waiting
     210        recursion_count--;
     211        if ( recursion_count == 0 ) {
     212                pop_and_set_new_owner( this );
     213        }
     214        unlock( lock );
     215}
     216
     217static inline void on_notify(simple_owner_lock & this, struct thread$ * t ) with(this) {
     218        lock( lock __cfaabi_dbg_ctx2 );
     219        // lock held
     220        if ( owner != 0p ) {
     221                insert_last( blocked_threads, *t );
     222                unlock( lock );
     223        }
     224        // lock not held
     225        else {
     226                owner = t;
     227                recursion_count = 1;
     228                unpark( t );
     229                unlock( lock );
     230        }
     231}
     232
     233static inline size_t on_wait(simple_owner_lock & this) with(this) {
     234        lock( lock __cfaabi_dbg_ctx2 );
     235        /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
     236        /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
     237
     238        size_t ret = recursion_count;
     239
     240        pop_and_set_new_owner( this );
     241
     242        unlock( lock );
     243        return ret;
     244}
     245
     246static inline void on_wakeup(simple_owner_lock & this, size_t recursion ) with(this) { recursion_count = recursion; }
     247
    178248
    179249//-----------------------------------------------------------------------------
     
    194264        void ^?{}( alarm_node_wrap(L) & this ) { }
    195265
    196         static void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
     266        void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
    197267                // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
    198268                lock( cond->lock __cfaabi_dbg_ctx2 );
     
    218288
    219289        // this casts the alarm node to our wrapped type since we used type erasure
    220         static void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
     290        void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
    221291}
    222292
     
    235305        void ^?{}( condition_variable(L) & this ){ }
    236306
    237         static void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
     307        void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
    238308                if(&popped != 0p) {
    239309                        popped.signalled = true;
     
    280350        int counter( condition_variable(L) & this ) with(this) { return count; }
    281351
    282         static size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
     352        size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
    283353                // add info_thread to waiting queue
    284354                insert_last( blocked_threads, *i );
     
    293363
    294364        // helper for wait()'s' with no timeout
    295         static void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
     365        void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
    296366                lock( lock __cfaabi_dbg_ctx2 );
    297367                size_t recursion_count = queue_and_get_recursion(this, &i);
     
    310380
    311381        // helper for wait()'s' with a timeout
    312         static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
     382        void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
    313383                lock( lock __cfaabi_dbg_ctx2 );
    314384                size_t recursion_count = queue_and_get_recursion(this, &info);
     
    345415        // fast_cond_var
    346416        void  ?{}( fast_cond_var(L) & this ){
    347                 this.blocked_threads{};
     417                this.blocked_threads{}; 
    348418                #ifdef __CFA_DEBUG__
    349419                this.lock_used = 0p;
Note: See TracChangeset for help on using the changeset viewer.