Changes in / [1e6f632f:62a7cc0]


Ignore:
Location:
libcfa/src/concurrency
Files:
3 edited

Legend:

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

    r1e6f632f r62a7cc0  
    55#include <stdlib.hfa>
    66
    7 //-----------------------------------------------------------------------------
    8 // info_thread
     7///////////////////////////////////////////////////////////////////
     8//// info_thread
     9///////////////////////////////////////////////////////////////////
     10
    911forall(dtype L | is_blocking_lock(L)) {
    10         struct info_thread {
    11                 // used to put info_thread on a dl queue (aka sequence)
    12                 inline Seqable;
    13 
    14                 // waiting thread
    15                 struct $thread * t;
    16 
    17                 // shadow field
    18                 uintptr_t info;
    19 
    20                 // lock that is passed to wait() (if one is passed)
    21                 L * lock;
    22 
    23                 // true when signalled and false when timeout wakes thread
    24                 bool signalled;
    25         };
    26 
    27         void ?{}( info_thread(L) & this, $thread * t, uintptr_t info, L * l ) {
     12        void ?{}( info_thread(L) & this, $thread * t ) {
     13                ((Seqable &) this){};
     14                this.t = t;
     15                this.lock = 0p;
     16        }
     17
     18        void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) {
    2819                ((Seqable &) this){};
    2920                this.t = t;
    3021                this.info = info;
    31                 this.lock = l;
    32         }
    33 
    34         void ^?{}( info_thread(L) & this ) {}
     22                this.lock = 0p;
     23        }
     24
     25        void ^?{}( info_thread(L) & this ){ }
    3526
    3627        info_thread(L) *& Back( info_thread(L) * this ) {
     
    4334}
    4435
    45 //-----------------------------------------------------------------------------
    46 // Blocking Locks
     36///////////////////////////////////////////////////////////////////
     37//// Blocking Locks
     38///////////////////////////////////////////////////////////////////
     39
    4740void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ) {
    4841        this.lock{};
     
    5649
    5750void ^?{}( blocking_lock & this ) {}
    58 void  ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
     51void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
    5952void ^?{}( single_acquisition_lock & this ) {}
    60 void  ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
     53void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
    6154void ^?{}( owner_lock & this ) {}
    62 void  ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
     55void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
    6356void ^?{}( multiple_acquisition_lock & this ) {}
    6457
    6558void lock( blocking_lock & this ) with( this ) {
    6659        lock( lock __cfaabi_dbg_ctx2 );
    67         $thread * thrd = active_thread();
    68 
    69         // single acquisition lock is held by current thread
    70         /* paranoid */ verifyf( owner != thrd || multi_acquisition, "Single acquisition lock holder (%p) attempted to reacquire the lock %p resulting in a deadlock.", owner, &this );
    71 
    72         // lock is held by some other thread
    73         if ( owner != 0p && owner != thrd ) {
    74                 addTail( blocked_threads, *thrd );
     60        if ( owner == active_thread() && !multi_acquisition) { // single acquisition lock is held by current thread
     61                abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock.");
     62        } else if ( owner != 0p && owner != active_thread() ) { // lock is held by some other thread
     63                addTail( blocked_threads, *active_thread() );
    7564                wait_count++;
    7665                unlock( lock );
    7766                park( );
    78         }
    79         // multi acquisition lock is held by current thread
    80         else if ( owner == thrd && multi_acquisition ) {
     67        } else if ( owner == active_thread() && multi_acquisition ) { // multi acquisition lock is held by current thread
    8168                recursion_count++;
    8269                unlock( lock );
    83         }
    84         // lock isn't held
    85         else {
    86                 owner = thrd;
     70        } else { // lock isn't held
     71                owner = active_thread();
    8772                recursion_count = 1;
    8873                unlock( lock );
     
    9378        bool ret = false;
    9479        lock( lock __cfaabi_dbg_ctx2 );
    95 
    96         // lock isn't held
    97         if ( owner == 0p ) {
     80        if ( owner == 0p ) { // lock isn't held
    9881                owner = active_thread();
    9982                recursion_count = 1;
    10083                ret = true;
    101         }
    102         // multi acquisition lock is held by current thread
    103         else if ( owner == active_thread() && multi_acquisition ) {
     84        } else if ( owner == active_thread() && multi_acquisition ) { // multi acquisition lock is held by current thread
    10485                recursion_count++;
    10586                ret = true;
    10687        }
    107 
    10888        unlock( lock );
    10989        return ret;
     90}
     91
     92void unlock_error_check( blocking_lock & this ) with( this ) {
     93        if ( owner == 0p ){ // lock isn't held
     94                abort( "There was an attempt to release a lock that isn't held" );
     95        } else if ( strict_owner && owner != active_thread() ) {
     96                abort( "A thread other than the owner attempted to release an owner lock" );
     97        }
    11098}
    11199
     
    120108void unlock( blocking_lock & this ) with( this ) {
    121109        lock( lock __cfaabi_dbg_ctx2 );
    122         /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
    123         /* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
    124 
    125         // if recursion count is zero release lock and set new owner if one is waiting
     110        unlock_error_check( this );
    126111        recursion_count--;
    127         if ( recursion_count == 0 ) {
     112        if ( recursion_count == 0 ) { // if recursion count is zero release lock and set new owner if one is waiting
    128113                pop_and_set_new_owner( this );
    129114        }
     
    144129
    145130void on_notify( blocking_lock & this, $thread * t ) with( this ) {
    146         lock( lock __cfaabi_dbg_ctx2 );
    147         // lock held
    148         if ( owner != 0p ) {
     131    lock( lock __cfaabi_dbg_ctx2 );
     132        if ( owner != 0p ) { // lock held
    149133                addTail( blocked_threads, *t );
    150134                wait_count++;
    151135                unlock( lock );
    152         }
    153         // lock not held
    154         else {
     136        } else {        // lock not held
    155137                owner = t;
    156138                recursion_count = 1;
     
    161143
    162144void on_wait( blocking_lock & this ) with( this ) {
    163         lock( lock __cfaabi_dbg_ctx2 );
    164         /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
    165         /* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
    166 
     145    lock( lock __cfaabi_dbg_ctx2 );
     146        unlock_error_check( this );
    167147        pop_and_set_new_owner( this );
    168148        unlock( lock );
    169149}
    170150
    171 //-----------------------------------------------------------------------------
    172 // Overloaded routines for traits
     151///////////////////////////////////////////////////////////////////
     152//// Overloaded routines for traits
     153///////////////////////////////////////////////////////////////////
     154
    173155// These routines are temporary until an inheritance bug is fixed
    174 void   lock      ( single_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
    175 void   unlock    ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
    176 void   on_wait   ( single_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
    177 void   on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    178 void   set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
    179 size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
    180 
    181 void   lock     ( owner_lock & this ) { lock   ( (blocking_lock &)this ); }
    182 void   unlock   ( owner_lock & this ) { unlock ( (blocking_lock &)this ); }
    183 void   on_wait  ( owner_lock & this ) { on_wait( (blocking_lock &)this ); }
    184 void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    185 void   set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
    186 size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
    187 
    188 void   lock     ( multiple_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
    189 void   unlock   ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
    190 void   on_wait  ( multiple_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
    191 void   on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
    192 void   set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
     156
     157void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
     158void unlock( single_acquisition_lock & this ){ unlock( (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 ); }
     161void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
     162size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     163
     164void lock( owner_lock & this ){ lock( (blocking_lock &)this ); }
     165void unlock( owner_lock & this ){ unlock( (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 ); }
     168void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
     169size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     170
     171void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
     172void unlock( multiple_acquisition_lock & this ){ unlock( (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 ); }
     175void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    193176size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
    194177
    195 //-----------------------------------------------------------------------------
    196 // alarm node wrapper
     178///////////////////////////////////////////////////////////////////
     179//// condition variable
     180///////////////////////////////////////////////////////////////////
     181
    197182forall(dtype L | is_blocking_lock(L)) {
    198         struct alarm_node_wrap {
    199                 alarm_node_t alarm_node;
    200                 condition_variable(L) * cond;
    201                 info_thread(L) * i;
    202         };
    203 
    204         void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback, condition_variable(L) * c, info_thread(L) * i ) {
    205                 this.alarm_node{ callback, alarm, period };
    206                 this.cond = c;
    207                 this.i = i;
    208         }
    209 
    210         void ^?{}( alarm_node_wrap(L) & this ) { }
    211183
    212184        void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
    213                 // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
    214                 lock( cond->lock __cfaabi_dbg_ctx2 );
    215 
    216                 // this check is necessary to avoid a race condition since this timeout handler
    217                 //      may still be called after a thread has been removed from the queue but
    218                 //      before the alarm is unregistered
    219                 if ( listed(i) ) {      // is thread on queue
    220                         i->signalled = false;
    221                         // remove this thread O(1)
    222                         remove( cond->blocked_threads, *i );
     185        // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
     186            lock( cond->lock __cfaabi_dbg_ctx2 );
     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
     192                i->signalled = false;
     193                        remove( cond->blocked_threads, *i );    // remove this thread O(1)
    223194                        cond->count--;
    224195                        if( i->lock ) {
    225                                 // call lock's on_notify if a lock was passed
    226                                 on_notify(*i->lock, i->t);
    227                         } else {
    228                                 // otherwise wake thread
    229                                 unpark( i->t );
    230                         }
    231                 }
    232                 unlock( cond->lock );
     196                                on_notify(*i->lock, i->t);                      // call lock's on_notify if a lock was passed
     197                } else {
     198                        unpark( i->t );                                         // otherwise wake thread
     199                }
     200            }
     201            unlock( cond->lock );
    233202        }
    234203
    235204        // this casts the alarm node to our wrapped type since we used type erasure
    236205        void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
    237 }
    238 
    239 //-----------------------------------------------------------------------------
    240 // condition variable
    241 forall(dtype L | is_blocking_lock(L)) {
    242206
    243207        void ?{}( condition_variable(L) & this ){
     
    248212
    249213        void ^?{}( condition_variable(L) & this ){ }
     214
     215        void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback ) {
     216                this.alarm_node{ callback, alarm, period };
     217        }
     218
     219        void ^?{}( alarm_node_wrap(L) & this ) { }
    250220
    251221        void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
     
    254224                        count--;
    255225                        if (popped.lock) {
    256                                 // if lock passed call on_notify
    257                                 on_notify(*popped.lock, popped.t);
     226                                on_notify(*popped.lock, popped.t); // if lock passed call on_notify
    258227                        } else {
    259                                 // otherwise wake thread
    260                                 unpark(popped.t);
     228                                unpark(popped.t); // otherwise wake thread
    261229                        }
    262230                }
     
    290258
    291259        size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
    292                 // add info_thread to waiting queue
    293                 addTail( blocked_threads, *i );
     260                addTail( blocked_threads, *i ); // add info_thread to waiting queue
    294261                count++;
    295262                size_t recursion_count = 0;
    296                 if (i->lock) {
    297                         // if lock was passed get recursion count to reset to after waking thread
     263                if (i->lock) { // if lock was passed get recursion count to reset to after waking thread
    298264                        recursion_count = get_recursion_count(*i->lock);
    299265                        on_wait( *i->lock );
     
    307273                size_t recursion_count = queue_and_get_recursion(this, &i);
    308274                unlock( lock );
    309 
    310                 // blocks here
    311                 park( );
    312 
    313                 // resets recursion count here after waking
    314                 if (i.lock) set_recursion_count(*i.lock, recursion_count);
    315         }
    316 
    317         #define WAIT( u, l ) \
    318                 info_thread( L ) i = { active_thread(), u, l }; \
    319                 queue_info_thread( this, i );
     275                park( ); // blocks here
     276                if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking
     277        }
    320278
    321279        // helper for wait()'s' with a timeout
     
    323281                lock( lock __cfaabi_dbg_ctx2 );
    324282                size_t recursion_count = queue_and_get_recursion(this, &info);
    325                 alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast, &this, &info };
     283                alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast };
     284                node_wrap.cond = &this;
     285                node_wrap.i = &info;
    326286                register_self( &node_wrap.alarm_node );
    327287                unlock( lock );
    328 
    329                 // blocks here
    330288                park();
    331 
    332                 // unregisters alarm so it doesn't go off if this happens first
    333                 unregister_self( &node_wrap.alarm_node );
    334 
    335                 // resets recursion count here after waking
    336                 if (info.lock) set_recursion_count(*info.lock, recursion_count);
    337         }
    338 
    339         #define WAIT_TIME( u, l, t ) \
    340                 info_thread( L ) i = { active_thread(), u, l }; \
    341                 queue_info_thread_timeout(this, i, t ); \
    342                 return i.signalled;
    343 
    344         void wait( condition_variable(L) & this                        ) with(this) { WAIT( 0, 0p    ) }
    345         void wait( condition_variable(L) & this, uintptr_t info        ) with(this) { WAIT( info, 0p ) }
    346         void wait( condition_variable(L) & this, L & l                 ) with(this) { WAIT( 0, &l    ) }
    347         void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) { WAIT( info, &l ) }
    348 
    349         bool wait( condition_variable(L) & this, Duration duration                        ) with(this) { WAIT_TIME( 0   , 0p , __kernel_get_time() + duration ) }
    350         bool wait( condition_variable(L) & this, uintptr_t info, Duration duration        ) with(this) { WAIT_TIME( info, 0p , __kernel_get_time() + duration ) }
    351         bool wait( condition_variable(L) & this, Time time                                ) with(this) { WAIT_TIME( 0   , 0p , time ) }
    352         bool wait( condition_variable(L) & this, uintptr_t info, Time time                ) with(this) { WAIT_TIME( info, 0p , time ) }
    353         bool wait( condition_variable(L) & this, L & l, Duration duration                 ) with(this) { WAIT_TIME( 0   , &l , __kernel_get_time() + duration ) }
    354         bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , __kernel_get_time() + duration ) }
    355         bool wait( condition_variable(L) & this, L & l, Time time                         ) with(this) { WAIT_TIME( 0   , &l , time ) }
    356         bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time         ) with(this) { WAIT_TIME( info, &l , time ) }
    357 }
     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
     291        }
     292
     293        void wait( condition_variable(L) & this ) with(this) {
     294                info_thread( L ) i = { active_thread() };
     295                queue_info_thread( this, i );
     296        }
     297
     298        void wait( condition_variable(L) & this, uintptr_t info ) with(this) {
     299                info_thread( L ) i = { active_thread(), info };
     300                queue_info_thread( this, i );
     301        }
     302       
     303        bool wait( condition_variable(L) & this, Duration duration ) with(this) {
     304                info_thread( L ) i = { active_thread() };
     305                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     306                return i.signalled;
     307        }
     308
     309        bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) {
     310                info_thread( L ) i = { active_thread(), info };
     311                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     312                return i.signalled;
     313        }
     314
     315        bool wait( condition_variable(L) & this, Time time ) with(this) {
     316                info_thread( L ) i = { active_thread() };
     317                queue_info_thread_timeout(this, i, time);
     318                return i.signalled;
     319        }
     320
     321        bool wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) {
     322                info_thread( L ) i = { active_thread(), info };
     323                queue_info_thread_timeout(this, i, time);
     324                return i.signalled;
     325        }
     326
     327        void wait( condition_variable(L) & this, L & l ) with(this) {
     328                info_thread(L) i = { active_thread() };
     329                i.lock = &l;
     330                queue_info_thread( this, i );
     331        }
     332
     333        void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) {
     334                info_thread(L) i = { active_thread(), info };
     335                i.lock = &l;
     336                queue_info_thread( this, i );
     337        }
     338       
     339        bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) {
     340                info_thread(L) i = { active_thread() };
     341                i.lock = &l;
     342                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     343                return i.signalled;
     344        }
     345       
     346        bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
     347                info_thread(L) i = { active_thread(), info };
     348                i.lock = &l;
     349                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     350                return i.signalled;
     351        }
     352       
     353        bool wait( condition_variable(L) & this, L & l, Time time ) with(this) {
     354                info_thread(L) i = { active_thread() };
     355                i.lock = &l;
     356                queue_info_thread_timeout(this, i, time );
     357                return i.signalled;
     358        }
     359       
     360        bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) {
     361                info_thread(L) i = { active_thread(), info };
     362                i.lock = &l;
     363                queue_info_thread_timeout(this, i, time );
     364                return i.signalled;
     365        }
     366}
  • libcfa/src/concurrency/locks.hfa

    r1e6f632f r62a7cc0  
    33#include <stdbool.h>
    44
     5#include "bits/algorithm.hfa"
    56#include "bits/locks.hfa"
    67#include "bits/sequence.hfa"
     
    1011#include "time_t.hfa"
    1112#include "time.hfa"
     13#include <sys/time.h>
     14#include "alarm.hfa"
    1215
    13 //-----------------------------------------------------------------------------
    14 // is_blocking_lock
     16///////////////////////////////////////////////////////////////////
     17//// is_blocking_lock
     18///////////////////////////////////////////////////////////////////
     19
    1520trait is_blocking_lock(dtype L | sized(L)) {
    16         // For synchronization locks to use when acquiring
    17         void on_notify( L &, struct $thread * );
    18 
    19         // For synchronization locks to use when releasing
    20         void on_wait( L & );
    21 
    22         // to get recursion count for cond lock to reset after waking
    23         size_t get_recursion_count( L & );
    24 
    25         // to set recursion count after getting signalled;
    26         void set_recursion_count( L &, size_t recursion );
     21        void on_notify( L &, struct $thread * );                        // For synchronization locks to use when acquiring
     22        void on_wait( L & );                                                            // For synchronization locks to use when releasing
     23        size_t get_recursion_count( L & );                                      // to get recursion count for cond lock to reset after waking
     24        void set_recursion_count( L &, size_t recursion );      // to set recursion count after getting signalled;
    2725};
    2826
    29 //-----------------------------------------------------------------------------
    30 // info_thread
     27///////////////////////////////////////////////////////////////////
     28//// info_thread
     29///////////////////////////////////////////////////////////////////
     30
    3131// the info thread is a wrapper around a thread used
    3232// to store extra data for use in the condition variable
    3333forall(dtype L | is_blocking_lock(L)) {
    34         struct info_thread;
     34        struct info_thread {
     35                inline Seqable;                                 // used to put info_thread on a dl queue (aka sequence)
     36                struct $thread * t;                             // waiting thread
     37                uintptr_t info;                                 // shadow field
     38                L * lock;                                               // lock that is passed to wait() (if one is passed)
     39                bool signalled;                                 // true when signalled and false when timeout wakes thread
     40        };
     41
     42
     43        void ?{}( info_thread(L) & this, $thread * t );
     44        void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
     45        void ^?{}( info_thread(L) & this );
    3546
    3647        // for use by sequence
     
    3950}
    4051
    41 //-----------------------------------------------------------------------------
    42 // Blocking Locks
     52///////////////////////////////////////////////////////////////////
     53//// Blocking Locks
     54///////////////////////////////////////////////////////////////////
     55
    4356struct blocking_lock {
    4457        // Spin lock used for mutual exclusion
     
    7689};
    7790
    78 void  ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
     91void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
    7992void ^?{}( blocking_lock & this );
    8093
    81 void  ?{}( single_acquisition_lock & this );
     94void ?{}( single_acquisition_lock & this );
    8295void ^?{}( single_acquisition_lock & this );
    8396
    84 void  ?{}( owner_lock & this );
     97void ?{}( owner_lock & this );
    8598void ^?{}( owner_lock & this );
    8699
    87 void  ?{}( multiple_acquisition_lock & this );
     100void ?{}( multiple_acquisition_lock & this );
    88101void ^?{}( multiple_acquisition_lock & this );
    89102
     
    118131size_t get_recursion_count( multiple_acquisition_lock & this );
    119132
    120 //-----------------------------------------------------------------------------
    121 // Synchronization Locks
     133///////////////////////////////////////////////////////////////////
     134//// Synchronization Locks
     135///////////////////////////////////////////////////////////////////
    122136forall(dtype L | is_blocking_lock(L)) {
    123137        struct condition_variable {
     
    132146        };
    133147
    134         void  ?{}( condition_variable(L) & this );
     148        void ?{}( condition_variable(L) & this );
    135149        void ^?{}( condition_variable(L) & this );
     150
     151        struct alarm_node_wrap {
     152                alarm_node_t alarm_node;
     153
     154                condition_variable(L) * cond;
     155
     156                info_thread(L) * i;
     157        };
     158
     159        void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback );
     160        void ^?{}( alarm_node_wrap(L) & this );
     161
     162        void alarm_node_callback( alarm_node_wrap(L) & this );
     163
     164        void alarm_node_wrap_cast( alarm_node_t & a );
    136165
    137166        bool notify_one( condition_variable(L) & this );
     
    140169        uintptr_t front( condition_variable(L) & this );
    141170
    142         bool empty  ( condition_variable(L) & this );
    143         int  counter( condition_variable(L) & this );
     171        bool empty( condition_variable(L) & this );
     172        int counter( condition_variable(L) & this );
    144173
    145174        void wait( condition_variable(L) & this );
  • libcfa/src/concurrency/thread.cfa

    r1e6f632f r62a7cc0  
    133133
    134134        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
    135         /* paranoid */ verify( this_thrd->context.SP );
     135        verify( this_thrd->context.SP );
    136136
    137137        __schedule_thread( this_thrd );
Note: See TracChangeset for help on using the changeset viewer.