Ignore:
File:
1 edited

Legend:

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

    rbeeff61e rfece3d9  
    4444// - change messy big blocking lock from inheritance to composition to remove need for flags
    4545
     46typedef void (*__cfa_pre_park)( void * );
     47
     48static inline void pre_park_noop( void * ) {}
     49
     50//-----------------------------------------------------------------------------
     51// is_blocking_lock
     52forall( L & | sized(L) )
     53trait is_blocking_lock {
     54        // For synchronization locks to use when acquiring
     55        void on_notify( L &, struct thread$ * );
     56
     57        // For synchronization locks to use when releasing
     58        size_t on_wait( L &, __cfa_pre_park pp_fn, void * pp_datum );
     59
     60        // to set recursion count after getting signalled;
     61        void on_wakeup( L &, size_t recursion );
     62};
     63
     64static inline void pre_park_then_park( __cfa_pre_park pp_fn, void * pp_datum ) {
     65    pp_fn( pp_datum );
     66    park();
     67}
     68
    4669//-----------------------------------------------------------------------------
    4770// Semaphore
     
    6992static inline bool   try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); }
    7093static inline void   unlock   ( single_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
    71 static inline size_t on_wait  ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); }
     94static inline size_t on_wait  ( single_acquisition_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum ); }
    7295static inline void   on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    7396static inline void   on_notify( single_acquisition_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
     
    86109static inline bool   try_lock ( owner_lock & this ) { return try_lock( (blocking_lock &)this ); }
    87110static inline void   unlock   ( owner_lock & this ) { unlock  ( (blocking_lock &)this ); }
    88 static inline size_t on_wait  ( owner_lock & this ) { return on_wait ( (blocking_lock &)this ); }
     111static inline size_t on_wait  ( owner_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum ); }
    89112static inline void   on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    90113static inline void   on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
     
    218241
    219242static inline void on_notify( futex_mutex & f, thread$ * t){ unpark(t); }
    220 static inline size_t on_wait( futex_mutex & f ) { unlock(f); park(); return 0; }
     243static inline size_t on_wait( futex_mutex & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     244    unlock( this );
     245    pre_park_then_park( pp_fn, pp_datum );
     246    return 0;
     247}
    221248
    222249// to set recursion count after getting signalled;
     
    288315
    289316static inline void on_notify( go_mutex & f, thread$ * t){ unpark( t ); }
    290 static inline size_t on_wait( go_mutex & f ) { unlock( f ); park(); return 0; }
     317static inline size_t on_wait( go_mutex & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     318    unlock( this );
     319    pre_park_then_park( pp_fn, pp_datum );
     320    return 0;
     321}
    291322static inline void on_wakeup( go_mutex & f, size_t recursion ) {}
    292323
     
    362393
    363394static inline void on_notify( exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark( t ); }
    364 static inline size_t on_wait( exp_backoff_then_block_lock & this ) { unlock( this ); park(); return 0; }
     395static inline size_t on_wait( exp_backoff_then_block_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     396    unlock( this );
     397    pre_park_then_park( pp_fn, pp_datum );
     398    return 0;
     399}
    365400static inline void on_wakeup( exp_backoff_then_block_lock & this, size_t recursion ) { lock( this ); }
    366401
     
    419454    unlock( lock );
    420455}
    421 static inline size_t on_wait( fast_block_lock & this) { unlock(this); park(); return 0; }
     456static inline size_t on_wait( fast_block_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     457    unlock( this );
     458    pre_park_then_park( pp_fn, pp_datum );
     459    return 0;
     460}
    422461static inline void on_wakeup( fast_block_lock & this, size_t recursion ) { }
    423462
     
    497536}
    498537
    499 static inline void on_notify(simple_owner_lock & this, thread$ * t ) with(this) {
     538static inline void on_notify( simple_owner_lock & this, thread$ * t ) with(this) {
    500539        lock( lock __cfaabi_dbg_ctx2 );
    501540        // lock held
     
    512551}
    513552
    514 static inline size_t on_wait( simple_owner_lock & this ) with(this) {
     553static inline size_t on_wait( simple_owner_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) with(this) {
    515554        lock( lock __cfaabi_dbg_ctx2 );
    516555        /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
     
    524563    active_thread()->link_node = (void *)&node;
    525564        unlock( lock );
    526     park();
     565
     566    pre_park_then_park( pp_fn, pp_datum );
    527567
    528568        return ret;
     
    624664        unpark(t);
    625665}
    626 static inline size_t on_wait( spin_queue_lock & this ) { unlock( this ); park(); return 0; }
     666static inline size_t on_wait( spin_queue_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     667    unlock( this );
     668    pre_park_then_park( pp_fn, pp_datum );
     669    return 0;
     670}
    627671static inline void on_wakeup( spin_queue_lock & this, size_t recursion ) { lock( this ); }
    628672
     
    665709
    666710static inline void on_notify( mcs_block_spin_lock & this, struct thread$ * t ) { unpark( t ); }
    667 static inline size_t on_wait( mcs_block_spin_lock & this) { unlock( this ); park(); return 0; }
     711static inline size_t on_wait( mcs_block_spin_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     712    unlock( this );
     713    pre_park_then_park( pp_fn, pp_datum );
     714    return 0;
     715}
    668716static inline void on_wakeup( mcs_block_spin_lock & this, size_t recursion ) {lock( this ); }
    669717
     
    717765        unpark(t);
    718766}
    719 static inline size_t on_wait( block_spin_lock & this ) { unlock( this ); park(); return 0; }
     767static inline size_t on_wait( block_spin_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) {
     768    unlock( this );
     769    pre_park_then_park( pp_fn, pp_datum );
     770    return 0;
     771}
    720772static inline void on_wakeup( block_spin_lock & this, size_t recursion ) with(this) {
    721773        // now we acquire the entire block_spin_lock upon waking up
     
    724776        unlock( lock ); // Now we release the internal fast_spin_lock
    725777}
    726 
    727 //-----------------------------------------------------------------------------
    728 // is_blocking_lock
    729 forall( L & | sized(L) )
    730 trait is_blocking_lock {
    731         // For synchronization locks to use when acquiring
    732         void on_notify( L &, struct thread$ * );
    733 
    734         // For synchronization locks to use when releasing
    735         size_t on_wait( L & );
    736 
    737         // to set recursion count after getting signalled;
    738         void on_wakeup( L &, size_t recursion );
    739 };
    740778
    741779//-----------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.