Changes in / [3febb2d:7d651a6]


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

Legend:

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

    r3febb2d r7d651a6  
    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         type = User;
     52        kernel_alarm = false;
    5353}
    5454
     
    5858        this.period = period;
    5959        set = false;
    60         type = Kernel;
    61 }
    62 void ?{}( 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;
     60        kernel_alarm = true;
    6961}
    7062
  • libcfa/src/concurrency/alarm.hfa

    r3febb2d r7d651a6  
    3939//=============================================================================================
    4040
    41 enum alarm_type{ Kernel = 0, User = 1, Callback = 2 };
    42 
    43 struct alarm_node_t;
    44 
    45 typedef void (*Alarm_Callback)(alarm_node_t & );
    46 
    4741struct alarm_node_t {
    4842        Time alarm;                             // time when alarm goes off
     
    5650        };
    5751
    58         Alarm_Callback callback;
    59 
    6052        bool set                :1;             // whether or not the alarm has be registered
    61         enum alarm_type type;           // true if this is not a user defined alarm
     53        bool kernel_alarm       :1;             // true if this is not a user defined alarm
    6254};
    6355DLISTED_MGD_IMPL_OUT(alarm_node_t)
     
    6557void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period );
    6658void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period );
    67 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
    6859void ^?{}( alarm_node_t & this );
    6960
  • libcfa/src/concurrency/locks.cfa

    r3febb2d r7d651a6  
    1515                this.t = t;
    1616                this.lock = 0p;
    17                 this.listed = false;
    1817        }
    1918
     
    2221                this.info = info;
    2322                this.lock = 0p;
    24                 this.listed = false;
    2523        }
    2624
     
    7977        if ( owner == kernelTLS.this_thread && !multi_acquisition) {
    8078                fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
    81         exit(EXIT_FAILURE);
     79                exit(EXIT_FAILURE);
    8280        } else if ( owner != 0p && owner != kernelTLS.this_thread ) {
    8381                append( blocked_threads, kernelTLS.this_thread );
    8482                wait_count++;
    8583                unlock( lock );
    86                 park( );
     84                park( __cfaabi_dbg_ctx );
    8785        } else if ( owner == kernelTLS.this_thread && multi_acquisition ) {
    8886                recursion_count++;
     
    113111        lock( lock __cfaabi_dbg_ctx2 );
    114112        if ( owner == 0p ){ // no owner implies lock isn't held
    115                 fprintf( stderr, "There was an attempt to release a lock that isn't held" ); 
     113                fprintf( stderr, "There was an attempt to release a lock that isn't held" );
    116114                return;
    117115        } else if ( strict_owner && owner != kernelTLS.this_thread ) {
    118                 fprintf( stderr, "A thread other than the owner attempted to release an owner lock" ); 
     116                fprintf( stderr, "A thread other than the owner attempted to release an owner lock" );
    119117                return;
    120118        }
     
    125123                recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
    126124                wait_count--;
    127                 unpark( thrd );
     125                unpark( thrd __cfaabi_dbg_ctx2 );
    128126        }
    129127        unlock( lock );
     
    152150                owner = t;
    153151                if ( multi_acquisition ) recursion_count = 1;
    154                 #if !defined( __CFA_NO_STATISTICS__ )
    155                         kernelTLS.this_stats = t->curr_cluster->stats;
    156                 #endif
    157                 unpark( t );
     152                unpark( t __cfaabi_dbg_ctx2 );
    158153                unlock( lock );
    159154        }
     
    163158    lock( lock __cfaabi_dbg_ctx2 );
    164159        if ( owner == 0p ){ // no owner implies lock isn't held
    165                 fprintf( stderr, "A lock that is not held was passed to a synchronization lock" ); 
     160                fprintf( stderr, "A lock that is not held was passed to a synchronization lock" );
    166161        } else if ( strict_owner && owner != kernelTLS.this_thread ) {
    167                 fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" ); 
     162                fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" );
    168163        } else {
    169164                $thread * thrd = pop_head( blocked_threads );
     
    171166                recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
    172167                wait_count--;
    173                 unpark( thrd );
     168                unpark( thrd __cfaabi_dbg_ctx2 );
    174169        }
    175170        unlock( lock );
     
    180175///////////////////////////////////////////////////////////////////
    181176
    182 // This is temporary until an inheritance bug is fixed
     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
    183180
    184181void lock( mutex_lock & this ){
     
    231228
    232229///////////////////////////////////////////////////////////////////
    233 //// condition variable
     230//// Synchronization Locks
    234231///////////////////////////////////////////////////////////////////
    235232
    236233forall(dtype L | is_blocking_lock(L)) {
    237 
    238         void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
    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                         cond->wait_count--;
    245                         if( !copy->lock ) {
    246                                 unlock( cond->lock );
    247                                 #if !defined( __CFA_NO_STATISTICS__ )
    248                                         kernelTLS.this_stats = copy->t->curr_cluster->stats;
    249                                 #endif
    250                                 unpark( copy->t );
    251                 } else {
    252                         add_(*copy->lock, copy->t);                     // call lock's add_
    253                 }
    254             }
    255             unlock( cond->lock );
    256         }
    257 
    258         void alarm_node_wrap_cast( alarm_node_t & a ) {
    259                 timeout_handler( (alarm_node_wrap(L) &)a );
    260         }
    261 
    262         void ?{}( condition_variable(L) & this ){
     234        void ?{}( synchronization_lock(L) & this, bool reacquire_after_signal ){
    263235                this.lock{};
    264236                this.blocked_threads{};
    265237                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 };
    266247        }
    267248
     
    270251        }
    271252
    272         void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) {
    273                 this.alarm_node{ thrd, alarm, period, callback };
    274         }
    275 
    276         void ^?{}( alarm_node_wrap(L) & this ) {
    277                 // default
    278         }
    279 
    280         bool notify_one( condition_variable(L) & this ) with( this ) {
     253        void ?{}( thread_queue(L) & this ){
     254                ((synchronization_lock(L) &)this){ false };
     255        }
     256
     257        void ^?{}( thread_queue(L) & this ){
     258                // default
     259        }
     260
     261        bool notify_one( synchronization_lock(L) & this ) with( this ) {
    281262                lock( lock __cfaabi_dbg_ctx2 );
    282263                bool ret = !!blocked_threads;
    283264                info_thread(L) * popped = pop_head( blocked_threads );
    284                 popped->listed = false;
    285265                if(popped != 0p) {
    286                         count--;
    287                         if (popped->lock) {
     266                        if( reacquire_after_signal ){
    288267                                add_(*popped->lock, popped->t);
    289268                        } else {
    290                                 unpark(popped->t);
     269                                unpark(
     270                                        popped->t __cfaabi_dbg_ctx2
     271                                );
    291272                        }
    292273                }
     
    295276        }
    296277
    297         bool notify_all( condition_variable(L) & this ) with(this) {
     278        bool notify_all( synchronization_lock(L) & this ) with(this) {
    298279                lock( lock __cfaabi_dbg_ctx2 );
    299280                bool ret = blocked_threads ? true : false;
    300281                while( blocked_threads ) {
    301282                        info_thread(L) * popped = pop_head( blocked_threads );
    302                         popped->listed = false;
    303283                        if(popped != 0p){
    304                                 count--;
    305                                 if (popped->lock) {
     284                                if( reacquire_after_signal ){
    306285                                        add_(*popped->lock, popped->t);
    307286                                } else {
    308                                         unpark(popped->t);
     287                                        unpark(
     288                                                popped->t __cfaabi_dbg_ctx2
     289                                        );
    309290                                }
    310291                        }
     
    314295        }
    315296
    316         uintptr_t front( condition_variable(L) & this ) with(this) {
    317                 if(!blocked_threads) return NULL;
    318                 return peek(blocked_threads)->info;
    319         }
    320 
    321         bool empty( condition_variable(L) & this ) with(this) {
     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) {
    322302                return blocked_threads ? false : true;
    323303        }
    324304
    325         int counter( condition_variable(L) & this ) with(this) {
     305        int counter( synchronization_lock(L) & this ) with(this) {
    326306                return count;
    327307        }
    328308
    329         // helper for wait()'s' without a timeout
    330         void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
     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) {
    331349                lock( lock __cfaabi_dbg_ctx2 );
    332350                append( this.blocked_threads, &i );
    333351                count++;
    334                 i.listed = true;
    335                 size_t recursion_count;
    336                 if (i.lock) {
    337                         recursion_count = get_recursion_count(*i.lock);
    338                         remove_( *i.lock );
    339                 }
    340                
    341                 unlock( lock );
    342                 park( ); // blocks here
    343 
    344                 if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking
    345         }
    346 
    347         // helper for wait()'s' with a timeout
    348         void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Time t ) with(this) {
    349                 lock( lock __cfaabi_dbg_ctx2 );
    350 
    351                 info_thread(L) * queue_ptr = &info;
    352 
    353                 alarm_node_wrap(L) node_wrap = { info.t, t, 0`s, alarm_node_wrap_cast };
    354                 node_wrap.cond = &this;
    355                 node_wrap.i = &queue_ptr;
    356 
    357                 register_self( &node_wrap.alarm_node );
    358 
    359                 append( blocked_threads, queue_ptr );
    360                 info.listed = true;
    361                 count++;
    362 
    363                 size_t recursion_count;
    364                 if (info.lock) {
    365                         recursion_count = get_recursion_count(*info.lock);
    366                         remove_( *info.lock );
    367                 }
    368 
    369                 unlock( lock );
    370                 park();
    371 
    372                 if (info.lock) set_recursion_count(*info.lock, recursion_count);
    373         }
    374 
    375         void wait( condition_variable(L) & this ) with(this) {
    376                 info_thread( L ) i = { kernelTLS.this_thread };
    377                 queue_info_thread( this, i );
    378         }
    379 
    380         void wait( condition_variable(L) & this, uintptr_t info ) with(this) {
    381                 info_thread( L ) i = { kernelTLS.this_thread, info };
    382                 queue_info_thread( this, i );
    383         }
    384        
    385         void wait( condition_variable(L) & this, Duration duration ) with(this) {
    386                 info_thread( L ) i = { kernelTLS.this_thread };
    387                 queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    388         }
    389 
    390         void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) {
    391                 info_thread( L ) i = { kernelTLS.this_thread, info };
    392                 queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    393         }
    394 
    395         void wait( condition_variable(L) & this, Time time ) with(this) {
    396                 info_thread( L ) i = { kernelTLS.this_thread };
    397                 queue_info_thread_timeout(this, i, time);
    398         }
    399 
    400         void wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) {
    401                 info_thread( L ) i = { kernelTLS.this_thread, info };
    402                 queue_info_thread_timeout(this, i, time);
    403         }
    404 
    405         void wait( condition_variable(L) & this, L & l ) with(this) {
     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) {
    406362                info_thread(L) i = { kernelTLS.this_thread };
    407                 i.lock = &l;
    408                 queue_info_thread( this, i );
    409         }
    410 
    411         void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) {
     363                queue_info_thread_unlock( this, l, i );
     364        }
     365
     366        void wait( synchronization_lock(L) & this, L & l, uintptr_t info ) with(this) {
    412367                info_thread(L) i = { kernelTLS.this_thread, info };
    413                 i.lock = &l;
    414                 queue_info_thread( this, i );
    415         }
    416        
    417         void wait( condition_variable(L) & this, L & l, Duration duration ) with(this) {
    418                 info_thread(L) i = { kernelTLS.this_thread };
    419                 i.lock = &l;
    420                 queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    421         }
    422        
    423         void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
    424                 info_thread(L) i = { kernelTLS.this_thread, info };
    425                 i.lock = &l;
    426                 queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    427         }
    428        
    429         void wait( condition_variable(L) & this, L & l, Time time ) with(this) {
    430                 info_thread(L) i = { kernelTLS.this_thread };
    431                 i.lock = &l;
    432                 queue_info_thread_timeout(this, i, time );
    433         }
    434        
    435         void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) {
    436                 info_thread(L) i = { kernelTLS.this_thread, info };
    437                 i.lock = &l;
    438                 queue_info_thread_timeout(this, i, time );
    439         }
    440 }
     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
     402forall(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}
  • libcfa/src/concurrency/locks.hfa

    r3febb2d r7d651a6  
    1 #pragma once
    2 
    31#include <stdbool.h>
    42
     
    1210#include "time.hfa"
    1311#include <sys/time.h>
    14 #include "alarm.hfa"
    1512
    1613///////////////////////////////////////////////////////////////////
     
    3532                info_thread(L) * next;
    3633                L * lock;
    37                 bool listed;                                    // true if info_thread is on queue, false otherwise;
    3834        };
    3935
     
    123119///////////////////////////////////////////////////////////////////
    124120forall(dtype L | is_blocking_lock(L)) {
    125         struct condition_variable {
     121        struct synchronization_lock {
    126122                // Spin lock used for mutual exclusion
    127123                __spinlock_t lock;
     
    132128                // Count of current blocked threads
    133129                int count;
    134         };
     130
     131                // If true threads will reacquire the lock they block on upon waking
     132                bool reacquire_after_signal;
     133        };
     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 );
    135146
    136147        void ?{}( condition_variable(L) & this );
    137148        void ^?{}( condition_variable(L) & this );
    138149
    139         struct alarm_node_wrap {
    140                 alarm_node_t alarm_node;
    141 
    142                 condition_variable(L) * cond;
    143 
    144                 info_thread(L) ** i;
    145         };
    146 
    147         void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
    148         void ^?{}( alarm_node_wrap(L) & this );
    149 
    150         void alarm_node_callback( alarm_node_wrap(L) & this );
    151 
    152         void alarm_node_wrap_cast( alarm_node_t & a );
    153 
    154         bool notify_one( condition_variable(L) & this );
    155         bool notify_all( condition_variable(L) & this );
    156 
    157         uintptr_t front( condition_variable(L) & this );
    158 
    159         bool empty( condition_variable(L) & this );
    160         int counter( condition_variable(L) & this );
    161 
    162         // TODO: look into changing timout routines to return bool showing if signalled or woken by kernel
    163         void wait( condition_variable(L) & this );
    164         void wait( condition_variable(L) & this, uintptr_t info );
    165         void wait( condition_variable(L) & this, Duration duration );
    166         void wait( condition_variable(L) & this, uintptr_t info, Duration duration );
    167         void wait( condition_variable(L) & this, Time time );
    168         void wait( condition_variable(L) & this, uintptr_t info, Time time );
    169 
    170         void wait( condition_variable(L) & this, L & l );
    171         void wait( condition_variable(L) & this, L & l, uintptr_t info );
    172         void wait( condition_variable(L) & this, L & l, Duration duration );
    173         void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
    174         void wait( condition_variable(L) & this, L & l, Time time );
    175         void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
     150        void ?{}( thread_queue(L) & this );
     151        void ^?{}( thread_queue(L) & this );
     152
     153        bool notify_one( synchronization_lock(L) & this );
     154        bool notify_all( synchronization_lock(L) & this );
     155
     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 );
    176179}
     180
     181///////////////////////////////////////////////////////////////////
     182//// condition lock alternative approach
     183///////////////////////////////////////////////////////////////////
     184
     185
     186///////////////////////////////////////////////////////////////////
     187//// is_simple_lock
     188///////////////////////////////////////////////////////////////////
     189
     190trait 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
     197forall(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;
     203        };
     204
     205        void ?{}( condition_lock(L) & this );
     206        void ^?{}( condition_lock(L) & this );
     207
     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 );
     211}
  • libcfa/src/concurrency/preemption.cfa

    r3febb2d r7d651a6  
    105105
    106106                // Check if this is a kernel
    107                 if( node->type == Kernel ) {
     107                if( node->kernel_alarm ) {
    108108                        preempt( node->proc );
    109109                }
    110                 else if( node->type == User ) {
     110                else {
    111111                        timeout( node->thrd );
    112                 }
    113                 else {
    114                         node->callback(*node);
    115112                }
    116113
Note: See TracChangeset for help on using the changeset viewer.