Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/monitor.c

    rde737c8 r34c6c767  
    1717
    1818#include <stdlib>
     19#include <inttypes.h>
    1920
    2021#include "libhdr.h"
     
    2627// Forward declarations
    2728static inline void set_owner ( monitor_desc * this, thread_desc * owner );
    28 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner );
    29 static inline void set_mask  ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
     29static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner );
     30static inline void set_mask  ( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask );
    3031static inline void reset_mask( monitor_desc * this );
    3132
     
    3334static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors );
    3435
    35 static inline void lock_all( spinlock ** locks, unsigned short count );
    36 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );
    37 static inline void unlock_all( spinlock ** locks, unsigned short count );
    38 static inline void unlock_all( monitor_desc ** locks, unsigned short count );
    39 
    40 static inline void save   ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks );
    41 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks );
    42 
    43 static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
    44 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     36static inline void lock_all  ( __spinlock_t * locks [], __lock_size_t count );
     37static inline void lock_all  ( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count );
     38static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count );
     39static inline void unlock_all( monitor_desc * locks [], __lock_size_t count );
     40
     41static inline void save   ( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );
     42static inline void restore( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
     43
     44static inline void init     ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
     45static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
    4546
    4647static inline thread_desc *        check_condition   ( __condition_criterion_t * );
    47 static inline void                 brand_condition   ( condition * );
    48 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count );
     48static inline void                 brand_condition   ( condition & );
     49static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count );
    4950
    5051forall(dtype T | sized( T ))
    51 static inline short insert_unique( T ** array, short & size, T * val );
    52 static inline short count_max    ( const __waitfor_mask_t & mask );
    53 static inline short aggregate    ( monitor_desc ** storage, const __waitfor_mask_t & mask );
     52static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val );
     53static inline __lock_size_t count_max    ( const __waitfor_mask_t & mask );
     54static inline __lock_size_t aggregate    ( monitor_desc * storage [], const __waitfor_mask_t & mask );
     55
     56#ifndef __CFA_LOCK_NO_YIELD
     57#define DO_LOCK lock_yield
     58#else
     59#define DO_LOCK lock
     60#endif
    5461
    5562//-----------------------------------------------------------------------------
     
    5865        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    5966        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    60         init( count, monitors, &waiter, criteria );               /* Link everything together                                                            */ \
     67        init( count, monitors, waiter, criteria );                /* Link everything together                                                            */ \
    6168
    6269#define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack                         */ \
    6370        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    6471        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    65         init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack                                */ \
     72        init_push( count, monitors, waiter, criteria );           /* Link everything together and push it to the AS-Stack                                */ \
    6673
    6774#define monitor_ctx( mons, cnt )                                /* Define that create the necessary struct for internal/external scheduling operations */ \
    6875        monitor_desc ** monitors = mons;                          /* Save the targeted monitors                                                          */ \
    69         unsigned short count = cnt;                               /* Save the count to a local variable                                                  */ \
     76        __lock_size_t count = cnt;                                /* Save the count to a local variable                                                  */ \
    7077        unsigned int recursions[ count ];                         /* Save the current recursion levels to restore them later                             */ \
    71         __waitfor_mask_t masks[ count ];                          /* Save the current waitfor masks to restore them later                                */ \
    72         spinlock *   locks    [ count ];                         /* We need to pass-in an array of locks to BlockInternal                               */ \
     78        __waitfor_mask_t masks [ count ];                         /* Save the current waitfor masks to restore them later                                */ \
     79        __spinlock_t *   locks [ count ];                         /* We need to pass-in an array of locks to BlockInternal                               */ \
    7380
    7481#define monitor_save    save   ( monitors, count, locks, recursions, masks )
     
    8390        // Enter single monitor
    8491        static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
    85                 // Lock the monitor spinlock, lock_yield to reduce contention
    86                 lock_yield( &this->lock DEBUG_CTX2 );
     92                // Lock the monitor spinlock
     93                DO_LOCK( this->lock DEBUG_CTX2 );
    8794                thread_desc * thrd = this_thread;
    8895
     
    114121
    115122                        // Some one else has the monitor, wait in line for it
    116                         append( &this->entry_queue, thrd );
     123                        append( this->entry_queue, thrd );
    117124                        BlockInternal( &this->lock );
    118125
     
    126133
    127134                // Release the lock and leave
    128                 unlock( &this->lock );
     135                unlock( this->lock );
    129136                return;
    130137        }
    131138
    132139        static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    133                 // Lock the monitor spinlock, lock_yield to reduce contention
    134                 lock_yield( &this->lock DEBUG_CTX2 );
     140                // Lock the monitor spinlock
     141                DO_LOCK( this->lock DEBUG_CTX2 );
    135142                thread_desc * thrd = this_thread;
    136143
     
    144151                        set_owner( this, thrd );
    145152
    146                         unlock( &this->lock );
     153                        unlock( this->lock );
    147154                        return;
    148155                }
     
    153160                }
    154161
    155                 int count = 1;
     162                __lock_size_t count = 1;
    156163                monitor_desc ** monitors = &this;
    157164                __monitor_group_t group = { &this, 1, func };
     
    160167
    161168                        // Wake the thread that is waiting for this
    162                         __condition_criterion_t * urgent = pop( &this->signal_stack );
     169                        __condition_criterion_t * urgent = pop( this->signal_stack );
    163170                        verify( urgent );
    164171
     
    182189
    183190                        // Some one else has the monitor, wait in line for it
    184                         append( &this->entry_queue, thrd );
     191                        append( this->entry_queue, thrd );
    185192                        BlockInternal( &this->lock );
    186193
     
    195202        // Leave single monitor
    196203        void __leave_monitor_desc( monitor_desc * this ) {
    197                 // Lock the monitor spinlock, lock_yield to reduce contention
    198                 lock_yield( &this->lock DEBUG_CTX2 );
     204                // Lock the monitor spinlock, DO_LOCK to reduce contention
     205                DO_LOCK( this->lock DEBUG_CTX2 );
    199206
    200207                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
     
    209216                if( this->recursion != 0) {
    210217                        LIB_DEBUG_PRINT_SAFE("Kernel :  recursion still %d\n", this->recursion);
    211                         unlock( &this->lock );
     218                        unlock( this->lock );
    212219                        return;
    213220                }
     
    217224
    218225                // We can now let other threads in safely
    219                 unlock( &this->lock );
     226                unlock( this->lock );
    220227
    221228                //We need to wake-up the thread
     
    242249
    243250                // Lock the monitor now
    244                 lock_yield( &this->lock DEBUG_CTX2 );
     251                DO_LOCK( this->lock DEBUG_CTX2 );
    245252
    246253                disable_interrupts();
     
    272279// relies on the monitor array being sorted
    273280static inline void enter( __monitor_group_t monitors ) {
    274         for(int i = 0; i < monitors.size; i++) {
     281        for( __lock_size_t i = 0; i < monitors.size; i++) {
    275282                __enter_monitor_desc( monitors.list[i], monitors );
    276283        }
     
    279286// Leave multiple monitor
    280287// relies on the monitor array being sorted
    281 static inline void leave(monitor_desc ** monitors, int count) {
    282         for(int i = count - 1; i >= 0; i--) {
     288static inline void leave(monitor_desc * monitors [], __lock_size_t count) {
     289        for( __lock_size_t i = count - 1; i >= 0; i--) {
    283290                __leave_monitor_desc( monitors[i] );
    284291        }
     
    287294// Ctor for monitor guard
    288295// Sorts monitors before entering
    289 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
     296void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
    290297        // Store current array
    291298        this.m = m;
     
    296303
    297304        // Save previous thread context
    298         this.prev_mntrs = this_thread->monitors.list;
    299         this.prev_count = this_thread->monitors.size;
    300         this.prev_func  = this_thread->monitors.func;
     305        this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
    301306
    302307        // Update thread context (needed for conditions)
    303         this_thread->monitors.list = m;
    304         this_thread->monitors.size = count;
    305         this_thread->monitors.func = func;
     308        this_thread->monitors.[list, size, func] = [m, count, func];
    306309
    307310        // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     
    325328
    326329        // Restore thread context
    327         this_thread->monitors.list = this.prev_mntrs;
    328         this_thread->monitors.size = this.prev_count;
    329         this_thread->monitors.func = this.prev_func;
    330 }
    331 
     330        this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
     331}
    332332
    333333// Ctor for monitor guard
    334334// Sorts monitors before entering
    335 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) {
     335void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
    336336        // Store current array
    337337        this.m = *m;
    338338
    339339        // Save previous thread context
    340         this.prev_mntrs = this_thread->monitors.list;
    341         this.prev_count = this_thread->monitors.size;
    342         this.prev_func  = this_thread->monitors.func;
     340        this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
    343341
    344342        // Update thread context (needed for conditions)
    345         this_thread->monitors.list = m;
    346         this_thread->monitors.size = 1;
    347         this_thread->monitors.func = func;
     343        this_thread->monitors.[list, size, func] = [m, 1, func];
    348344
    349345        __enter_monitor_dtor( this.m, func );
    350346}
    351 
    352347
    353348// Dtor for monitor guard
     
    357352
    358353        // Restore thread context
    359         this_thread->monitors.list = this.prev_mntrs;
    360         this_thread->monitors.size = this.prev_count;
    361         this_thread->monitors.func = this.prev_func;
     354        this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
    362355}
    363356
    364357//-----------------------------------------------------------------------------
    365358// Internal scheduling types
    366 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
     359void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
    367360        this.waiting_thread = waiting_thread;
    368361        this.count = count;
     
    378371}
    379372
    380 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ) {
     373void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t & owner ) {
    381374        this.ready  = false;
    382375        this.target = target;
    383         this.owner  = owner;
     376        this.owner  = &owner;
    384377        this.next   = NULL;
    385378}
     
    387380//-----------------------------------------------------------------------------
    388381// Internal scheduling
    389 void wait( condition * this, uintptr_t user_info = 0 ) {
     382void wait( condition & this, uintptr_t user_info = 0 ) {
    390383        brand_condition( this );
    391384
    392385        // Check that everything is as expected
    393         assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    394         verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    395         verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
     386        assertf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors );
     387        verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count );
     388        verifyf( this.monitor_count < 32u, "Excessive monitor count (%"PRIiFAST16")", this.monitor_count );
    396389
    397390        // Create storage for monitor context
    398         monitor_ctx( this->monitors, this->monitor_count );
     391        monitor_ctx( this.monitors, this.monitor_count );
    399392
    400393        // Create the node specific to this wait operation
     
    403396        // Append the current wait operation to the ones already queued on the condition
    404397        // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
    405         append( &this->blocked, &waiter );
     398        append( this.blocked, &waiter );
    406399
    407400        // Lock all monitors (aggregates the locks as well)
     
    409402
    410403        // Find the next thread(s) to run
    411         short thread_count = 0;
     404        __lock_size_t thread_count = 0;
    412405        thread_desc * threads[ count ];
    413406        __builtin_memset( threads, 0, sizeof( threads ) );
     
    417410
    418411        // Remove any duplicate threads
    419         for( int i = 0; i < count; i++) {
     412        for( __lock_size_t i = 0; i < count; i++) {
    420413                thread_desc * new_owner = next_thread( monitors[i] );
    421414                insert_unique( threads, thread_count, new_owner );
     
    429422}
    430423
    431 bool signal( condition * this ) {
     424bool signal( condition & this ) {
    432425        if( is_empty( this ) ) { return false; }
    433426
    434427        //Check that everything is as expected
    435         verify( this->monitors );
    436         verify( this->monitor_count != 0 );
     428        verify( this.monitors );
     429        verify( this.monitor_count != 0 );
    437430
    438431        //Some more checking in debug
    439432        LIB_DEBUG_DO(
    440433                thread_desc * this_thrd = this_thread;
    441                 if ( this->monitor_count != this_thrd->monitors.size ) {
    442                         abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->monitors.size );
    443                 }
    444 
    445                 for(int i = 0; i < this->monitor_count; i++) {
    446                         if ( this->monitors[i] != this_thrd->monitors.list[i] ) {
    447                                 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->monitors.list[i] );
     434                if ( this.monitor_count != this_thrd->monitors.size ) {
     435                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", &this, this.monitor_count, this_thrd->monitors.size );
     436                }
     437
     438                for(int i = 0; i < this.monitor_count; i++) {
     439                        if ( this.monitors[i] != this_thrd->monitors.list[i] ) {
     440                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors.list[i] );
    448441                        }
    449442                }
    450443        );
    451444
    452         unsigned short count = this->monitor_count;
     445        __lock_size_t count = this.monitor_count;
    453446
    454447        // Lock all monitors
    455         lock_all( this->monitors, NULL, count );
     448        lock_all( this.monitors, NULL, count );
    456449
    457450        //Pop the head of the waiting queue
    458         __condition_node_t * node = pop_head( &this->blocked );
     451        __condition_node_t * node = pop_head( this.blocked );
    459452
    460453        //Add the thread to the proper AS stack
     
    462455                __condition_criterion_t * crit = &node->criteria[i];
    463456                assert( !crit->ready );
    464                 push( &crit->target->signal_stack, crit );
     457                push( crit->target->signal_stack, crit );
    465458        }
    466459
    467460        //Release
    468         unlock_all( this->monitors, count );
     461        unlock_all( this.monitors, count );
    469462
    470463        return true;
    471464}
    472465
    473 bool signal_block( condition * this ) {
    474         if( !this->blocked.head ) { return false; }
     466bool signal_block( condition & this ) {
     467        if( !this.blocked.head ) { return false; }
    475468
    476469        //Check that everything is as expected
    477         verifyf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    478         verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
     470        verifyf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors );
     471        verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count );
    479472
    480473        // Create storage for monitor context
    481         monitor_ctx( this->monitors, this->monitor_count );
     474        monitor_ctx( this.monitors, this.monitor_count );
    482475
    483476        // Lock all monitors (aggregates the locks them as well)
     
    491484
    492485        //Find the thread to run
    493         thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
     486        thread_desc * signallee = pop_head( this.blocked )->waiting_thread;
    494487        set_owner( monitors, count, signallee );
    495488
    496         LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", this, signallee );
     489        LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
    497490
    498491        //Everything is ready to go to sleep
     
    512505
    513506// Access the user_info of the thread waiting at the front of the queue
    514 uintptr_t front( condition * this ) {
     507uintptr_t front( condition & this ) {
    515508        verifyf( !is_empty(this),
    516509                "Attempt to access user data on an empty condition.\n"
    517510                "Possible cause is not checking if the condition is empty before reading stored data."
    518511        );
    519         return this->blocked.head->user_info;
     512        return this.blocked.head->user_info;
    520513}
    521514
     
    537530        // This statment doesn't have a contiguous list of monitors...
    538531        // Create one!
    539         short max = count_max( mask );
     532        __lock_size_t max = count_max( mask );
    540533        monitor_desc * mon_storage[max];
    541534        __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );
    542         short actual_count = aggregate( mon_storage, mask );
    543 
    544         LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (short)max);
     535        __lock_size_t actual_count = aggregate( mon_storage, mask );
     536
     537        LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);
    545538
    546539        if(actual_count == 0) return;
     
    569562
    570563                                __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
    571                                 push( &mon2dtor->signal_stack, dtor_crit );
     564                                push( mon2dtor->signal_stack, dtor_crit );
    572565
    573566                                unlock_all( locks, count );
     
    629622        set_mask( monitors, count, mask );
    630623
    631         for(int i = 0; i < count; i++) {
     624        for( __lock_size_t i = 0; i < count; i++) {
    632625                verify( monitors[i]->owner == this_thread );
    633626        }
     
    661654}
    662655
    663 static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) {
     656static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) {
    664657        monitors[0]->owner     = owner;
    665658        monitors[0]->recursion = 1;
    666         for( int i = 1; i < count; i++ ) {
     659        for( __lock_size_t i = 1; i < count; i++ ) {
    667660                monitors[i]->owner     = owner;
    668661                monitors[i]->recursion = 0;
     
    670663}
    671664
    672 static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {
    673         for(int i = 0; i < count; i++) {
     665static inline void set_mask( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask ) {
     666        for( __lock_size_t i = 0; i < count; i++) {
    674667                storage[i]->mask = mask;
    675668        }
     
    685678        //Check the signaller stack
    686679        LIB_DEBUG_PRINT_SAFE("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
    687         __condition_criterion_t * urgent = pop( &this->signal_stack );
     680        __condition_criterion_t * urgent = pop( this->signal_stack );
    688681        if( urgent ) {
    689682                //The signaller stack is not empty,
     
    697690        // No signaller thread
    698691        // Get the next thread in the entry_queue
    699         thread_desc * new_owner = pop_head( &this->entry_queue );
     692        thread_desc * new_owner = pop_head( this->entry_queue );
    700693        set_owner( this, new_owner );
    701694
     
    705698static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
    706699        __acceptable_t * it = this->mask.clauses; // Optim
    707         int count = this->mask.size;
     700        __lock_size_t count = this->mask.size;
    708701
    709702        // Check if there are any acceptable functions
     
    714707
    715708        // For all acceptable functions check if this is the current function.
    716         for( short i = 0; i < count; i++, it++ ) {
     709        for( __lock_size_t i = 0; i < count; i++, it++ ) {
    717710                if( *it == group ) {
    718711                        *this->mask.accepted = i;
     
    725718}
    726719
    727 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
    728         for(int i = 0; i < count; i++) {
     720static inline void init( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
     721        for( __lock_size_t i = 0; i < count; i++) {
    729722                (criteria[i]){ monitors[i], waiter };
    730723        }
    731724
    732         waiter->criteria = criteria;
    733 }
    734 
    735 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
    736         for(int i = 0; i < count; i++) {
     725        waiter.criteria = criteria;
     726}
     727
     728static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
     729        for( __lock_size_t i = 0; i < count; i++) {
    737730                (criteria[i]){ monitors[i], waiter };
    738731                LIB_DEBUG_PRINT_SAFE( "Kernel :  target %p = %p\n", criteria[i].target, &criteria[i] );
    739                 push( &criteria[i].target->signal_stack, &criteria[i] );
    740         }
    741 
    742         waiter->criteria = criteria;
    743 }
    744 
    745 static inline void lock_all( spinlock ** locks, unsigned short count ) {
    746         for( int i = 0; i < count; i++ ) {
    747                 lock_yield( locks[i] DEBUG_CTX2 );
    748         }
    749 }
    750 
    751 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ) {
    752         for( int i = 0; i < count; i++ ) {
    753                 spinlock * l = &source[i]->lock;
    754                 lock_yield( l DEBUG_CTX2 );
     732                push( criteria[i].target->signal_stack, &criteria[i] );
     733        }
     734
     735        waiter.criteria = criteria;
     736}
     737
     738static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) {
     739        for( __lock_size_t i = 0; i < count; i++ ) {
     740                DO_LOCK( *locks[i] DEBUG_CTX2 );
     741        }
     742}
     743
     744static inline void lock_all( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ) {
     745        for( __lock_size_t i = 0; i < count; i++ ) {
     746                __spinlock_t * l = &source[i]->lock;
     747                DO_LOCK( *l DEBUG_CTX2 );
    755748                if(locks) locks[i] = l;
    756749        }
    757750}
    758751
    759 static inline void unlock_all( spinlock ** locks, unsigned short count ) {
    760         for( int i = 0; i < count; i++ ) {
    761                 unlock( locks[i] );
    762         }
    763 }
    764 
    765 static inline void unlock_all( monitor_desc ** locks, unsigned short count ) {
    766         for( int i = 0; i < count; i++ ) {
    767                 unlock( &locks[i]->lock );
    768         }
    769 }
    770 
    771 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
    772         for( int i = 0; i < count; i++ ) {
     752static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count ) {
     753        for( __lock_size_t i = 0; i < count; i++ ) {
     754                unlock( *locks[i] );
     755        }
     756}
     757
     758static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) {
     759        for( __lock_size_t i = 0; i < count; i++ ) {
     760                unlock( locks[i]->lock );
     761        }
     762}
     763
     764static inline void save(
     765        monitor_desc * ctx [],
     766        __lock_size_t count,
     767        __attribute((unused)) __spinlock_t * locks [],
     768        unsigned int /*out*/ recursions [],
     769        __waitfor_mask_t /*out*/ masks []
     770) {
     771        for( __lock_size_t i = 0; i < count; i++ ) {
    773772                recursions[i] = ctx[i]->recursion;
    774773                masks[i]      = ctx[i]->mask;
     
    776775}
    777776
    778 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
     777static inline void restore(
     778        monitor_desc * ctx [],
     779        __lock_size_t count,
     780        __spinlock_t * locks [],
     781        unsigned int /*out*/ recursions [],
     782        __waitfor_mask_t /*out*/ masks []
     783) {
    779784        lock_all( locks, count );
    780         for( int i = 0; i < count; i++ ) {
     785        for( __lock_size_t i = 0; i < count; i++ ) {
    781786                ctx[i]->recursion = recursions[i];
    782787                ctx[i]->mask      = masks[i];
     
    811816}
    812817
    813 static inline void brand_condition( condition * this ) {
     818static inline void brand_condition( condition & this ) {
    814819        thread_desc * thrd = this_thread;
    815         if( !this->monitors ) {
     820        if( !this.monitors ) {
    816821                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    817822                assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
    818                 this->monitor_count = thrd->monitors.size;
    819 
    820                 this->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );
    821                 for( int i = 0; i < this->monitor_count; i++ ) {
    822                         this->monitors[i] = thrd->monitors.list[i];
    823                 }
    824         }
    825 }
    826 
    827 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) {
    828 
    829         __thread_queue_t * entry_queue = &monitors[0]->entry_queue;
     823                this.monitor_count = thrd->monitors.size;
     824
     825                this.monitors = malloc( this.monitor_count * sizeof( *this.monitors ) );
     826                for( int i = 0; i < this.monitor_count; i++ ) {
     827                        this.monitors[i] = thrd->monitors.list[i];
     828                }
     829        }
     830}
     831
     832static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * monitors [], __lock_size_t count ) {
     833
     834        __thread_queue_t & entry_queue = monitors[0]->entry_queue;
    830835
    831836        // For each thread in the entry-queue
    832         for(    thread_desc ** thrd_it = &entry_queue->head;
     837        for(    thread_desc ** thrd_it = &entry_queue.head;
    833838                *thrd_it;
    834839                thrd_it = &(*thrd_it)->next
     
    852857
    853858forall(dtype T | sized( T ))
    854 static inline short insert_unique( T ** array, short & size, T * val ) {
     859static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) {
    855860        if( !val ) return size;
    856861
    857         for(int i = 0; i <= size; i++) {
     862        for( __lock_size_t i = 0; i <= size; i++) {
    858863                if( array[i] == val ) return size;
    859864        }
     
    864869}
    865870
    866 static inline short count_max( const __waitfor_mask_t & mask ) {
    867         short max = 0;
    868         for( int i = 0; i < mask.size; i++ ) {
     871static inline __lock_size_t count_max( const __waitfor_mask_t & mask ) {
     872        __lock_size_t max = 0;
     873        for( __lock_size_t i = 0; i < mask.size; i++ ) {
    869874                max += mask.clauses[i].size;
    870875        }
     
    872877}
    873878
    874 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {
    875         short size = 0;
    876         for( int i = 0; i < mask.size; i++ ) {
     879static inline __lock_size_t aggregate( monitor_desc * storage [], const __waitfor_mask_t & mask ) {
     880        __lock_size_t size = 0;
     881        for( __lock_size_t i = 0; i < mask.size; i++ ) {
    877882                __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size );
    878                 for( int j = 0; j < mask.clauses[i].size; j++) {
     883                for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) {
    879884                        insert_unique( storage, size, mask.clauses[i].list[j] );
    880885                }
     
    890895}
    891896
    892 void append( __condition_blocked_queue_t * this, __condition_node_t * c ) {
    893         verify(this->tail != NULL);
    894         *this->tail = c;
    895         this->tail = &c->next;
    896 }
    897 
    898 __condition_node_t * pop_head( __condition_blocked_queue_t * this ) {
    899         __condition_node_t * head = this->head;
     897void append( __condition_blocked_queue_t & this, __condition_node_t * c ) {
     898        verify(this.tail != NULL);
     899        *this.tail = c;
     900        this.tail = &c->next;
     901}
     902
     903__condition_node_t * pop_head( __condition_blocked_queue_t & this ) {
     904        __condition_node_t * head = this.head;
    900905        if( head ) {
    901                 this->head = head->next;
     906                this.head = head->next;
    902907                if( !head->next ) {
    903                         this->tail = &this->head;
     908                        this.tail = &this.head;
    904909                }
    905910                head->next = NULL;
Note: See TracChangeset for help on using the changeset viewer.