Changeset eeb5023


Ignore:
Timestamp:
Nov 5, 2020, 3:32:05 PM (3 years ago)
Author:
Colby Alexander Parsons <caparsons@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
c5bbb9b
Parents:
c28ea4e
Message:

added full timeout functionality to unified condition variables

Location:
libcfa/src/concurrency
Files:
5 edited

Legend:

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

    rc28ea4e reeb5023  
    4545//=============================================================================================
    4646
    47 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period ) with( this ) {
     47void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period) with( this ) {
    4848        this.thrd = thrd;
    4949        this.alarm = alarm;
    5050        this.period = period;
    5151        set = false;
    52         kernel_alarm = false;
     52        type = User;
    5353}
    5454
     
    5858        this.period = period;
    5959        set = false;
    60         kernel_alarm = true;
     60        type = Kernel;
     61}
     62void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) with( this ) {
     63        this.thrd = thrd;
     64        this.alarm = alarm;
     65        this.period = period;
     66        this.callback = callback;
     67        set = false;
     68        type = Callback;
    6169}
    6270
  • libcfa/src/concurrency/alarm.hfa

    rc28ea4e reeb5023  
    3939//=============================================================================================
    4040
     41enum alarm_type{ Kernel = 0, User = 1, Callback = 2 };
     42
     43struct alarm_node_t;
     44
     45typedef void (*Alarm_Callback)(alarm_node_t & );
     46
    4147struct alarm_node_t {
    4248        Time alarm;                             // time when alarm goes off
     
    5056        };
    5157
     58        Alarm_Callback callback;
     59
    5260        bool set                :1;             // whether or not the alarm has be registered
    53         bool kernel_alarm       :1;             // true if this is not a user defined alarm
     61        enum alarm_type type;           // true if this is not a user defined alarm
    5462};
    5563DLISTED_MGD_IMPL_OUT(alarm_node_t)
     
    5765void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period );
    5866void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period );
     67void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
    5968void ^?{}( alarm_node_t & this );
    6069
  • libcfa/src/concurrency/locks.cfa

    rc28ea4e reeb5023  
    1515                this.t = t;
    1616                this.lock = 0p;
     17                this.listed = false;
    1718        }
    1819
     
    2122                this.info = info;
    2223                this.lock = 0p;
     24                this.listed = false;
    2325        }
    2426
     
    7779        if ( owner == kernelTLS.this_thread && !multi_acquisition) {
    7880                fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
    79                 exit(EXIT_FAILURE);
     81        exit(EXIT_FAILURE);
    8082        } else if ( owner != 0p && owner != kernelTLS.this_thread ) {
    8183                append( blocked_threads, kernelTLS.this_thread );
    8284                wait_count++;
    8385                unlock( lock );
    84                 park( __cfaabi_dbg_ctx );
     86                park( );
    8587        } else if ( owner == kernelTLS.this_thread && multi_acquisition ) {
    8688                recursion_count++;
     
    111113        lock( lock __cfaabi_dbg_ctx2 );
    112114        if ( owner == 0p ){ // no owner implies lock isn't held
    113                 fprintf( stderr, "There was an attempt to release a lock that isn't held" );
     115                fprintf( stderr, "There was an attempt to release a lock that isn't held" ); 
    114116                return;
    115117        } else if ( strict_owner && owner != kernelTLS.this_thread ) {
    116                 fprintf( stderr, "A thread other than the owner attempted to release an owner lock" );
     118                fprintf( stderr, "A thread other than the owner attempted to release an owner lock" ); 
    117119                return;
    118120        }
     
    123125                recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
    124126                wait_count--;
    125                 unpark( thrd __cfaabi_dbg_ctx2 );
     127                unpark( thrd );
    126128        }
    127129        unlock( lock );
     
    150152                owner = t;
    151153                if ( multi_acquisition ) recursion_count = 1;
    152                 unpark( t __cfaabi_dbg_ctx2 );
     154                #if !defined( __CFA_NO_STATISTICS__ )
     155                        kernelTLS.this_stats = t->curr_cluster->stats;
     156                #endif
     157                unpark( t );
    153158                unlock( lock );
    154159        }
     
    158163    lock( lock __cfaabi_dbg_ctx2 );
    159164        if ( owner == 0p ){ // no owner implies lock isn't held
    160                 fprintf( stderr, "A lock that is not held was passed to a synchronization lock" );
     165                fprintf( stderr, "A lock that is not held was passed to a synchronization lock" ); 
    161166        } else if ( strict_owner && owner != kernelTLS.this_thread ) {
    162                 fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" );
     167                fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" ); 
    163168        } else {
    164169                $thread * thrd = pop_head( blocked_threads );
     
    166171                recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
    167172                wait_count--;
    168                 unpark( thrd __cfaabi_dbg_ctx2 );
     173                unpark( thrd );
    169174        }
    170175        unlock( lock );
     
    175180///////////////////////////////////////////////////////////////////
    176181
    177 // In an ideal world this may not be necessary
    178 // Is it possible for nominal inheritance to inherit traits??
    179 // If that occurs we would avoid all this extra code
     182// This is temporary until an inheritance bug is fixed
    180183
    181184void lock( mutex_lock & this ){
     
    228231
    229232///////////////////////////////////////////////////////////////////
    230 //// Synchronization Locks
     233//// condition variable
    231234///////////////////////////////////////////////////////////////////
    232235
    233236forall(dtype L | is_blocking_lock(L)) {
    234         void ?{}( synchronization_lock(L) & this, bool reacquire_after_signal ){
     237
     238        void timeout_handler ( condition_variable(L) * cond , info_thread(L) ** i ) {
     239        // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
     240            lock( cond->lock __cfaabi_dbg_ctx2 );
     241            if ( (*i)->listed ) {                       // is thread on queue
     242                info_thread(L) * copy = *i;
     243                        remove( cond->blocked_threads, i );              //remove this thread O(1)
     244                        if( !copy->lock ) {
     245                                unlock( cond->lock );
     246                                printf("here");
     247                                #if !defined( __CFA_NO_STATISTICS__ )
     248                                        kernelTLS.this_stats = copy->t->curr_cluster->stats;
     249                                #endif
     250                                unpark( copy->t );
     251                                printf("here2");
     252                } else {
     253                        add_(*copy->lock, copy->t);                     // call lock's add_
     254                }
     255            }
     256            unlock( cond->lock );
     257        }
     258
     259        void alarm_node_callback( alarm_node_wrap(L) & this ) with( this ) {
     260                timeout_handler(cond, i);
     261        }
     262
     263        void alarm_node_wrap_cast( alarm_node_t & a ) {
     264                alarm_node_callback( (alarm_node_wrap(L) &)a );
     265        }
     266
     267        void ?{}( condition_variable(L) & this ){
    235268                this.lock{};
    236269                this.blocked_threads{};
    237270                this.count = 0;
    238                 this.reacquire_after_signal = reacquire_after_signal;
    239         }
    240 
    241         void ^?{}( synchronization_lock(L) & this ){
    242                 // default
    243         }
    244 
    245         void ?{}( condition_variable(L) & this ){
    246                 ((synchronization_lock(L) &)this){ true };
    247271        }
    248272
     
    251275        }
    252276
    253         void ?{}( thread_queue(L) & this ){
    254                 ((synchronization_lock(L) &)this){ false };
    255         }
    256 
    257         void ^?{}( thread_queue(L) & this ){
     277        void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) {
     278                this.alarm_node{ thrd, alarm, period, callback };
     279        }
     280
     281        void ^?{}( alarm_node_wrap(L) & this ) {
    258282                // default
    259283        }
    260284
    261         bool notify_one( synchronization_lock(L) & this ) with( this ) {
     285        bool notify_one( condition_variable(L) & this ) with( this ) {
    262286                lock( lock __cfaabi_dbg_ctx2 );
    263287                bool ret = !!blocked_threads;
    264288                info_thread(L) * popped = pop_head( blocked_threads );
     289                popped->listed = false;
    265290                if(popped != 0p) {
    266                         if( reacquire_after_signal ){
    267                                 add_(*popped->lock, popped->t);
    268                         } else {
    269                                 unpark(
    270                                         popped->t __cfaabi_dbg_ctx2
    271                                 );
    272                         }
     291                        add_(*popped->lock, popped->t);
     292                        count--;
    273293                }
    274294                unlock( lock );
     
    276296        }
    277297
    278         bool notify_all( synchronization_lock(L) & this ) with(this) {
     298        bool notify_all( condition_variable(L) & this ) with(this) {
    279299                lock( lock __cfaabi_dbg_ctx2 );
    280300                bool ret = blocked_threads ? true : false;
    281301                while( blocked_threads ) {
    282302                        info_thread(L) * popped = pop_head( blocked_threads );
     303                        popped->listed = false;
    283304                        if(popped != 0p){
    284                                 if( reacquire_after_signal ){
    285                                         add_(*popped->lock, popped->t);
    286                                 } else {
    287                                         unpark(
    288                                                 popped->t __cfaabi_dbg_ctx2
    289                                         );
    290                                 }
     305                                add_(*popped->lock, popped->t);
     306                                count--;
    291307                        }
    292308                }
     
    295311        }
    296312
    297         uintptr_t front( synchronization_lock(L) & this ) with(this) {
    298                 return (*peek(blocked_threads)).info;
    299         }
    300 
    301         bool empty( synchronization_lock(L) & this ) with(this) {
     313        uintptr_t front( condition_variable(L) & this ) with(this) {
     314                if(!blocked_threads) return NULL;
     315                return peek(blocked_threads)->info;
     316        }
     317
     318        bool empty( condition_variable(L) & this ) with(this) {
    302319                return blocked_threads ? false : true;
    303320        }
    304321
    305         int counter( synchronization_lock(L) & this ) with(this) {
     322        int counter( condition_variable(L) & this ) with(this) {
    306323                return count;
    307324        }
    308325
    309         void queue_info_thread( synchronization_lock(L) & this, info_thread(L) & i ) with(this) {
    310                 lock( lock __cfaabi_dbg_ctx2 );
    311                 append( blocked_threads, &i );
    312                 count++;
    313                 unlock( lock );
    314                 park( __cfaabi_dbg_ctx );
    315         }
    316 
    317 
    318         void wait( synchronization_lock(L) & this ) with(this) {
    319                 info_thread( L ) i = { kernelTLS.this_thread };
    320                 queue_info_thread( this, i );
    321         }
    322 
    323         void wait( synchronization_lock(L) & this, uintptr_t info ) with(this) {
    324                 info_thread( L ) i = { kernelTLS.this_thread, info };
    325                 queue_info_thread( this, i );
    326         }
    327         // I still need to implement the time delay wait routines
    328         bool wait( synchronization_lock(L) & this, Duration duration ) with(this) {
    329                 timeval tv = { time(0) };
    330                 Time t = { tv };
    331                 return wait( this, t + duration );
    332         }
    333 
    334         bool wait( synchronization_lock(L) & this, uintptr_t info, Duration duration ) with(this) {
    335                 // TODO: ADD INFO
    336                 return wait( this, duration );
    337         }
    338 
    339         bool wait( synchronization_lock(L) & this, Time time ) with(this) {
    340                 return false; //default
    341         }
    342 
    343         bool wait( synchronization_lock(L) & this, uintptr_t info, Time time ) with(this) {
    344                 // TODO: ADD INFO
    345                 return wait( this, time );
    346         }
    347 
    348         void queue_info_thread_unlock( synchronization_lock(L) & this, L & l, info_thread(L) & i ) with(this) {
     326        // helper for wait()'s' without a timeout
     327        void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
    349328                lock( lock __cfaabi_dbg_ctx2 );
    350329                append( this.blocked_threads, &i );
    351330                count++;
    352                 i.lock = &l;
    353                 size_t recursion_count = get_recursion_count(l);
    354                 remove_( l );
    355                 unlock( lock );
    356                 park( __cfaabi_dbg_ctx ); // blocks here
    357 
    358                 set_recursion_count(l, recursion_count); // resets recursion count here after waking
    359         }
    360 
    361         void wait( synchronization_lock(L) & this, L & l ) with(this) {
     331                i.listed = true;
     332                size_t recursion_count;
     333                if (i.lock) {
     334                        recursion_count = get_recursion_count(*i.lock);
     335                        remove_( *i.lock );
     336                }
     337               
     338                unlock( lock );
     339                park( ); // blocks here
     340
     341                if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking
     342        }
     343
     344        // helper for wait()'s' with a timeout
     345        void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Time t ) with(this) {
     346                lock( lock __cfaabi_dbg_ctx2 );
     347
     348                info_thread(L) * queue_ptr = &info;
     349
     350                alarm_node_wrap(L) node_wrap = { info.t, t, 0`s, alarm_node_wrap_cast };
     351                node_wrap.cond = &this;
     352                node_wrap.i = &queue_ptr;
     353
     354                register_self( &node_wrap.alarm_node );
     355
     356                append( blocked_threads, queue_ptr );
     357                info.listed = true;
     358                count++;
     359
     360                size_t recursion_count;
     361                if (info.lock) {
     362                        recursion_count = get_recursion_count(*info.lock);
     363                        remove_( *info.lock );
     364                }
     365
     366                unlock( lock );
     367                park();
     368
     369                if (info.lock) set_recursion_count(*info.lock, recursion_count);
     370        }
     371
     372        void wait( condition_variable(L) & this ) with(this) {
     373                info_thread( L ) i = { kernelTLS.this_thread };
     374                queue_info_thread( this, i );
     375        }
     376
     377        void wait( condition_variable(L) & this, uintptr_t info ) with(this) {
     378                info_thread( L ) i = { kernelTLS.this_thread, info };
     379                queue_info_thread( this, i );
     380        }
     381       
     382        void wait( condition_variable(L) & this, Duration duration ) with(this) {
     383                info_thread( L ) i = { kernelTLS.this_thread };
     384                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     385        }
     386
     387        void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) {
     388                info_thread( L ) i = { kernelTLS.this_thread, info };
     389                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     390        }
     391
     392        void wait( condition_variable(L) & this, Time time ) with(this) {
     393                info_thread( L ) i = { kernelTLS.this_thread };
     394                queue_info_thread_timeout(this, i, time);
     395        }
     396
     397        void wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) {
     398                info_thread( L ) i = { kernelTLS.this_thread, info };
     399                queue_info_thread_timeout(this, i, time);
     400        }
     401
     402        void wait( condition_variable(L) & this, L & l ) with(this) {
    362403                info_thread(L) i = { kernelTLS.this_thread };
    363                 queue_info_thread_unlock( this, l, i );
    364         }
    365 
    366         void wait( synchronization_lock(L) & this, L & l, uintptr_t info ) with(this) {
     404                i.lock = &l;
     405                queue_info_thread( this, i );
     406        }
     407
     408        void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) {
    367409                info_thread(L) i = { kernelTLS.this_thread, info };
    368                 queue_info_thread_unlock( this, l, i );
    369         }
    370 
    371         bool wait( synchronization_lock(L) & this, L & l, Duration duration ) with(this) {
    372                 timeval tv = { time(0) };
    373                 Time t = { tv };
    374                 return wait( this, l, t + duration );
    375         }
    376 
    377         bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
    378                 // TODO: ADD INFO
    379                 return wait( this, l, duration );
    380         }
    381 
    382         bool wait( synchronization_lock(L) & this, L & l, Time time ) with(this) {
    383                 return false; //default
    384         }
    385 
    386         bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Time time ) with(this) {
    387                 // TODO: ADD INFO
    388                 return wait( this, l, time );
    389         }
    390 }
    391 
    392 ///////////////////////////////////////////////////////////////////
    393 //// condition lock alternative approach
    394 ///////////////////////////////////////////////////////////////////
    395 
    396 // the solution below is less efficient but does not require the lock to have a specific add/remove routine
    397 
    398 ///////////////////////////////////////////////////////////////////
    399 //// is_simple_lock
    400 ///////////////////////////////////////////////////////////////////
    401 
    402 forall(dtype L | is_simple_lock(L)) {
    403         void ?{}( condition_lock(L) & this ){
    404                 // default
    405         }
    406 
    407         void ^?{}( condition_lock(L) & this ){
    408                 // default
    409         }
    410 
    411         bool notify_one( condition_lock(L) & this ) with(this) {
    412                 return notify_one( c_var );
    413         }
    414 
    415         bool notify_all( condition_lock(L) & this ) with(this) {
    416                 return notify_all( c_var );
    417         }
    418 
    419         void wait( condition_lock(L) & this, L & l ) with(this) {
    420                 lock( m_lock );
    421                 size_t recursion = get_recursion_count( l );
    422                 unlock( l );
    423                 wait( c_var, m_lock );
    424                 lock( l );
    425                 set_recursion_count( l , recursion );
    426                 unlock( m_lock );
    427         }
    428 }
     410                i.lock = &l;
     411                queue_info_thread( this, i );
     412        }
     413       
     414        void wait( condition_variable(L) & this, L & l, Duration duration ) with(this) {
     415                info_thread(L) i = { kernelTLS.this_thread };
     416                i.lock = &l;
     417                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     418        }
     419       
     420        void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
     421                info_thread(L) i = { kernelTLS.this_thread, info };
     422                i.lock = &l;
     423                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
     424        }
     425       
     426        void wait( condition_variable(L) & this, L & l, Time time ) with(this) {
     427                info_thread(L) i = { kernelTLS.this_thread };
     428                i.lock = &l;
     429                queue_info_thread_timeout(this, i, time );
     430        }
     431       
     432        void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) {
     433                info_thread(L) i = { kernelTLS.this_thread, info };
     434                i.lock = &l;
     435                queue_info_thread_timeout(this, i, time );
     436        }
     437}
     438
     439thread T1 {};
     440thread T2 {};
     441
     442recursive_mutex_lock m;
     443condition_variable( recursive_mutex_lock ) c;
     444
     445void main( T1 & this ) {
     446        printf("T1 start\n");
     447        lock(m);
     448        printf("%d\n", counter(c));
     449        if(empty(c)) {
     450                printf("T1 wait\n");
     451                wait(c,m,12);
     452        }else{
     453                printf("%d\n", front(c));
     454                notify_one(c);
     455        }
     456        unlock(m);
     457        printf("curr thd in main %p \n", kernelTLS.this_thread);
     458        printf("T1 waits for 2s\n");
     459        lock(m);
     460        wait( c, m, 2`s );
     461        unlock(m);
     462        printf("T1 wakes\n");
     463        printf("T1 done\n");
     464}
     465
     466void main( T2 & this ) {
     467        printf("T2 start\n");
     468        lock(m);
     469        printf("%d\n", counter(c));
     470        if(empty(c)) {
     471                printf("T2 wait\n");
     472                wait(c,m,12);
     473        }else{
     474                printf("%d\n", front(c));
     475                notify_one(c);
     476        }
     477        unlock(m);
     478        printf("T2 done\n");
     479}
     480
     481int main() {
     482        printf("start\n");
     483        processor p[2];
     484        {
     485                T1 t1;
     486                T2 t2;
     487        }
     488        printf("done\n");
     489}
  • libcfa/src/concurrency/locks.hfa

    rc28ea4e reeb5023  
    1010#include "time.hfa"
    1111#include <sys/time.h>
     12#include "alarm.hfa"
    1213
    1314///////////////////////////////////////////////////////////////////
     
    3233                info_thread(L) * next;
    3334                L * lock;
     35                bool listed;                                    // true if info_thread is on queue, false otherwise;
    3436        };
    3537
     
    119121///////////////////////////////////////////////////////////////////
    120122forall(dtype L | is_blocking_lock(L)) {
    121         struct synchronization_lock {
     123        struct condition_variable {
    122124                // Spin lock used for mutual exclusion
    123125                __spinlock_t lock;
     
    128130                // Count of current blocked threads
    129131                int count;
    130 
    131                 // If true threads will reacquire the lock they block on upon waking
    132                 bool reacquire_after_signal;
    133132        };
    134 
    135         struct condition_variable {
    136                 inline synchronization_lock(L);
    137         };
    138 
    139         struct thread_queue {
    140                 inline synchronization_lock(L);
    141         };
    142 
    143 
    144         void ?{}( synchronization_lock(L) & this, bool multi_acquisition, bool strict_owner );
    145         void ^?{}( synchronization_lock(L) & this );
    146133
    147134        void ?{}( condition_variable(L) & this );
    148135        void ^?{}( condition_variable(L) & this );
    149136
    150         void ?{}( thread_queue(L) & this );
    151         void ^?{}( thread_queue(L) & this );
     137        struct alarm_node_wrap {
     138                alarm_node_t alarm_node;
    152139
    153         bool notify_one( synchronization_lock(L) & this );
    154         bool notify_all( synchronization_lock(L) & this );
     140                condition_variable(L) * cond;
    155141
    156         uintptr_t front( synchronization_lock(L) & this );
    157 
    158         bool empty( synchronization_lock(L) & this );
    159         int counter( synchronization_lock(L) & this );
    160 
    161         // wait functions that are not passed a mutex lock
    162         void wait( synchronization_lock(L) & this );
    163         void wait( synchronization_lock(L) & this, uintptr_t info );
    164         bool wait( synchronization_lock(L) & this, Duration duration );
    165         bool wait( synchronization_lock(L) & this, uintptr_t info, Duration duration );
    166         bool wait( synchronization_lock(L) & this, Time time );
    167         bool wait( synchronization_lock(L) & this, uintptr_t info, Time time );
    168 
    169         // wait functions that are passed a lock
    170         bool notify_one( synchronization_lock(L) & this, L & l );
    171         bool notify_all( synchronization_lock(L) & this, L & l );
    172 
    173         void wait( synchronization_lock(L) & this, L & l );
    174         void wait( synchronization_lock(L) & this, L & l, uintptr_t info );
    175         bool wait( synchronization_lock(L) & this, L & l, Duration duration );
    176         bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Duration duration );
    177         bool wait( synchronization_lock(L) & this, L & l, Time time );
    178         bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Time time );
    179 }
    180 
    181 ///////////////////////////////////////////////////////////////////
    182 //// condition lock alternative approach
    183 ///////////////////////////////////////////////////////////////////
    184 
    185 
    186 ///////////////////////////////////////////////////////////////////
    187 //// is_simple_lock
    188 ///////////////////////////////////////////////////////////////////
    189 
    190 trait is_simple_lock(dtype L | sized(L)) {
    191         void lock( L & );               // For synchronization locks to use when acquiring
    192         void unlock( L & );    // For synchronization locks to use when releasing
    193         size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
    194         void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
    195 };
    196 
    197 forall(dtype L | is_simple_lock(L)) {
    198         struct condition_lock {
    199                 // Spin lock used for mutual exclusion
    200                 mutex_lock m_lock;
    201 
    202                 condition_variable( mutex_lock ) c_var;
     142                info_thread(L) ** i;
    203143        };
    204144
    205         void ?{}( condition_lock(L) & this );
    206         void ^?{}( condition_lock(L) & this );
     145        void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
     146        void ^?{}( alarm_node_wrap(L) & this );
    207147
    208         bool notify_one( condition_lock(L) & this );
    209         bool notify_all( condition_lock(L) & this );
    210         void wait( condition_lock(L) & this, L & l );
     148        void alarm_node_callback( alarm_node_wrap(L) & this );
     149
     150        void alarm_node_wrap_cast( alarm_node_t & a );
     151
     152        bool notify_one( condition_variable(L) & this );
     153        bool notify_all( condition_variable(L) & this );
     154
     155        uintptr_t front( condition_variable(L) & this );
     156
     157        bool empty( condition_variable(L) & this );
     158        int counter( condition_variable(L) & this );
     159
     160        // TODO: look into changing timout routines to return bool showing if signalled or woken by kernel
     161        void wait( condition_variable(L) & this );
     162        void wait( condition_variable(L) & this, uintptr_t info );
     163        void wait( condition_variable(L) & this, Duration duration );
     164        void wait( condition_variable(L) & this, uintptr_t info, Duration duration );
     165        void wait( condition_variable(L) & this, Time time );
     166        void wait( condition_variable(L) & this, uintptr_t info, Time time );
     167
     168        void wait( condition_variable(L) & this, L & l );
     169        void wait( condition_variable(L) & this, L & l, uintptr_t info );
     170        void wait( condition_variable(L) & this, L & l, Duration duration );
     171        void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
     172        void wait( condition_variable(L) & this, L & l, Time time );
     173        void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
    211174}
  • libcfa/src/concurrency/preemption.cfa

    rc28ea4e reeb5023  
    112112                }
    113113                else {
    114                         bool unpark_thd = node->callback(*node);
    115                         if (unpark_thd) timeout( node->thrd );
     114                        node->callback(*node);
    116115                }
    117116
Note: See TracChangeset for help on using the changeset viewer.