Ignore:
File:
1 edited

Legend:

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

    r34c6c767 rde737c8  
    1717
    1818#include <stdlib>
    19 #include <inttypes.h>
    2019
    2120#include "libhdr.h"
     
    2726// Forward declarations
    2827static inline void set_owner ( monitor_desc * this, thread_desc * owner );
    29 static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner );
    30 static inline void set_mask  ( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask );
     28static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner );
     29static inline void set_mask  ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
    3130static inline void reset_mask( monitor_desc * this );
    3231
     
    3433static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors );
    3534
    36 static inline void lock_all  ( __spinlock_t * locks [], __lock_size_t count );
    37 static inline void lock_all  ( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count );
    38 static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count );
    39 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count );
    40 
    41 static inline void save   ( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );
    42 static inline void restore( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
    43 
    44 static inline void init     ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
    45 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
     35static inline void lock_all( spinlock ** locks, unsigned short count );
     36static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );
     37static inline void unlock_all( spinlock ** locks, unsigned short count );
     38static inline void unlock_all( monitor_desc ** locks, unsigned short count );
     39
     40static inline void save   ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks );
     41static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks );
     42
     43static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     44static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
    4645
    4746static inline thread_desc *        check_condition   ( __condition_criterion_t * );
    48 static inline void                 brand_condition   ( condition & );
    49 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count );
     47static inline void                 brand_condition   ( condition * );
     48static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count );
    5049
    5150forall(dtype T | sized( T ))
    52 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val );
    53 static inline __lock_size_t count_max    ( const __waitfor_mask_t & mask );
    54 static 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
     51static inline short insert_unique( T ** array, short & size, T * val );
     52static inline short count_max    ( const __waitfor_mask_t & mask );
     53static inline short aggregate    ( monitor_desc ** storage, const __waitfor_mask_t & mask );
    6154
    6255//-----------------------------------------------------------------------------
     
    6558        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    6659        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    67         init( count, monitors, waiter, criteria );                /* Link everything together                                                            */ \
     60        init( count, monitors, &waiter, criteria );               /* Link everything together                                                            */ \
    6861
    6962#define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack                         */ \
    7063        __condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                                     */ \
    7164        __condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up                            */ \
    72         init_push( count, monitors, waiter, criteria );           /* Link everything together and push it to the AS-Stack                                */ \
     65        init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack                                */ \
    7366
    7467#define monitor_ctx( mons, cnt )                                /* Define that create the necessary struct for internal/external scheduling operations */ \
    7568        monitor_desc ** monitors = mons;                          /* Save the targeted monitors                                                          */ \
    76         __lock_size_t count = cnt;                                /* Save the count to a local variable                                                  */ \
     69        unsigned short count = cnt;                               /* Save the count to a local variable                                                  */ \
    7770        unsigned int recursions[ count ];                         /* Save the current recursion levels to restore them later                             */ \
    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                               */ \
     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                               */ \
    8073
    8174#define monitor_save    save   ( monitors, count, locks, recursions, masks )
     
    9083        // Enter single monitor
    9184        static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
    92                 // Lock the monitor spinlock
    93                 DO_LOCK( this->lock DEBUG_CTX2 );
     85                // Lock the monitor spinlock, lock_yield to reduce contention
     86                lock_yield( &this->lock DEBUG_CTX2 );
    9487                thread_desc * thrd = this_thread;
    9588
     
    121114
    122115                        // Some one else has the monitor, wait in line for it
    123                         append( this->entry_queue, thrd );
     116                        append( &this->entry_queue, thrd );
    124117                        BlockInternal( &this->lock );
    125118
     
    133126
    134127                // Release the lock and leave
    135                 unlock( this->lock );
     128                unlock( &this->lock );
    136129                return;
    137130        }
    138131
    139132        static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    140                 // Lock the monitor spinlock
    141                 DO_LOCK( this->lock DEBUG_CTX2 );
     133                // Lock the monitor spinlock, lock_yield to reduce contention
     134                lock_yield( &this->lock DEBUG_CTX2 );
    142135                thread_desc * thrd = this_thread;
    143136
     
    151144                        set_owner( this, thrd );
    152145
    153                         unlock( this->lock );
     146                        unlock( &this->lock );
    154147                        return;
    155148                }
     
    160153                }
    161154
    162                 __lock_size_t count = 1;
     155                int count = 1;
    163156                monitor_desc ** monitors = &this;
    164157                __monitor_group_t group = { &this, 1, func };
     
    167160
    168161                        // Wake the thread that is waiting for this
    169                         __condition_criterion_t * urgent = pop( this->signal_stack );
     162                        __condition_criterion_t * urgent = pop( &this->signal_stack );
    170163                        verify( urgent );
    171164
     
    189182
    190183                        // Some one else has the monitor, wait in line for it
    191                         append( this->entry_queue, thrd );
     184                        append( &this->entry_queue, thrd );
    192185                        BlockInternal( &this->lock );
    193186
     
    202195        // Leave single monitor
    203196        void __leave_monitor_desc( monitor_desc * this ) {
    204                 // Lock the monitor spinlock, DO_LOCK to reduce contention
    205                 DO_LOCK( this->lock DEBUG_CTX2 );
     197                // Lock the monitor spinlock, lock_yield to reduce contention
     198                lock_yield( &this->lock DEBUG_CTX2 );
    206199
    207200                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
     
    216209                if( this->recursion != 0) {
    217210                        LIB_DEBUG_PRINT_SAFE("Kernel :  recursion still %d\n", this->recursion);
    218                         unlock( this->lock );
     211                        unlock( &this->lock );
    219212                        return;
    220213                }
     
    224217
    225218                // We can now let other threads in safely
    226                 unlock( this->lock );
     219                unlock( &this->lock );
    227220
    228221                //We need to wake-up the thread
     
    249242
    250243                // Lock the monitor now
    251                 DO_LOCK( this->lock DEBUG_CTX2 );
     244                lock_yield( &this->lock DEBUG_CTX2 );
    252245
    253246                disable_interrupts();
     
    279272// relies on the monitor array being sorted
    280273static inline void enter( __monitor_group_t monitors ) {
    281         for( __lock_size_t i = 0; i < monitors.size; i++) {
     274        for(int i = 0; i < monitors.size; i++) {
    282275                __enter_monitor_desc( monitors.list[i], monitors );
    283276        }
     
    286279// Leave multiple monitor
    287280// relies on the monitor array being sorted
    288 static inline void leave(monitor_desc * monitors [], __lock_size_t count) {
    289         for( __lock_size_t i = count - 1; i >= 0; i--) {
     281static inline void leave(monitor_desc ** monitors, int count) {
     282        for(int i = count - 1; i >= 0; i--) {
    290283                __leave_monitor_desc( monitors[i] );
    291284        }
     
    294287// Ctor for monitor guard
    295288// Sorts monitors before entering
    296 void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
     289void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
    297290        // Store current array
    298291        this.m = m;
     
    303296
    304297        // Save previous thread context
    305         this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
     298        this.prev_mntrs = this_thread->monitors.list;
     299        this.prev_count = this_thread->monitors.size;
     300        this.prev_func  = this_thread->monitors.func;
    306301
    307302        // Update thread context (needed for conditions)
    308         this_thread->monitors.[list, size, func] = [m, count, func];
     303        this_thread->monitors.list = m;
     304        this_thread->monitors.size = count;
     305        this_thread->monitors.func = func;
    309306
    310307        // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     
    328325
    329326        // Restore thread context
    330         this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
    331 }
     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
    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, prev_count, prev_func] = this_thread->monitors.[list, size, func];
     340        this.prev_mntrs = this_thread->monitors.list;
     341        this.prev_count = this_thread->monitors.size;
     342        this.prev_func  = this_thread->monitors.func;
    341343
    342344        // Update thread context (needed for conditions)
    343         this_thread->monitors.[list, size, func] = [m, 1, func];
     345        this_thread->monitors.list = m;
     346        this_thread->monitors.size = 1;
     347        this_thread->monitors.func = func;
    344348
    345349        __enter_monitor_dtor( this.m, func );
    346350}
     351
    347352
    348353// Dtor for monitor guard
     
    352357
    353358        // Restore thread context
    354         this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
     359        this_thread->monitors.list = this.prev_mntrs;
     360        this_thread->monitors.size = this.prev_count;
     361        this_thread->monitors.func = this.prev_func;
    355362}
    356363
    357364//-----------------------------------------------------------------------------
    358365// Internal scheduling types
    359 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
     366void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
    360367        this.waiting_thread = waiting_thread;
    361368        this.count = count;
     
    371378}
    372379
    373 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t & owner ) {
     380void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ) {
    374381        this.ready  = false;
    375382        this.target = target;
    376         this.owner  = &owner;
     383        this.owner  = owner;
    377384        this.next   = NULL;
    378385}
     
    380387//-----------------------------------------------------------------------------
    381388// Internal scheduling
    382 void wait( condition & this, uintptr_t user_info = 0 ) {
     389void wait( condition * this, uintptr_t user_info = 0 ) {
    383390        brand_condition( this );
    384391
    385392        // Check that everything is as expected
    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 );
     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 );
    389396
    390397        // Create storage for monitor context
    391         monitor_ctx( this.monitors, this.monitor_count );
     398        monitor_ctx( this->monitors, this->monitor_count );
    392399
    393400        // Create the node specific to this wait operation
     
    396403        // Append the current wait operation to the ones already queued on the condition
    397404        // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
    398         append( this.blocked, &waiter );
     405        append( &this->blocked, &waiter );
    399406
    400407        // Lock all monitors (aggregates the locks as well)
     
    402409
    403410        // Find the next thread(s) to run
    404         __lock_size_t thread_count = 0;
     411        short thread_count = 0;
    405412        thread_desc * threads[ count ];
    406413        __builtin_memset( threads, 0, sizeof( threads ) );
     
    410417
    411418        // Remove any duplicate threads
    412         for( __lock_size_t i = 0; i < count; i++) {
     419        for( int i = 0; i < count; i++) {
    413420                thread_desc * new_owner = next_thread( monitors[i] );
    414421                insert_unique( threads, thread_count, new_owner );
     
    422429}
    423430
    424 bool signal( condition & this ) {
     431bool signal( condition * this ) {
    425432        if( is_empty( this ) ) { return false; }
    426433
    427434        //Check that everything is as expected
    428         verify( this.monitors );
    429         verify( this.monitor_count != 0 );
     435        verify( this->monitors );
     436        verify( this->monitor_count != 0 );
    430437
    431438        //Some more checking in debug
    432439        LIB_DEBUG_DO(
    433440                thread_desc * this_thrd = this_thread;
    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] );
     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] );
    441448                        }
    442449                }
    443450        );
    444451
    445         __lock_size_t count = this.monitor_count;
     452        unsigned short count = this->monitor_count;
    446453
    447454        // Lock all monitors
    448         lock_all( this.monitors, NULL, count );
     455        lock_all( this->monitors, NULL, count );
    449456
    450457        //Pop the head of the waiting queue
    451         __condition_node_t * node = pop_head( this.blocked );
     458        __condition_node_t * node = pop_head( &this->blocked );
    452459
    453460        //Add the thread to the proper AS stack
     
    455462                __condition_criterion_t * crit = &node->criteria[i];
    456463                assert( !crit->ready );
    457                 push( crit->target->signal_stack, crit );
     464                push( &crit->target->signal_stack, crit );
    458465        }
    459466
    460467        //Release
    461         unlock_all( this.monitors, count );
     468        unlock_all( this->monitors, count );
    462469
    463470        return true;
    464471}
    465472
    466 bool signal_block( condition & this ) {
    467         if( !this.blocked.head ) { return false; }
     473bool signal_block( condition * this ) {
     474        if( !this->blocked.head ) { return false; }
    468475
    469476        //Check that everything is as expected
    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 );
     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 );
    472479
    473480        // Create storage for monitor context
    474         monitor_ctx( this.monitors, this.monitor_count );
     481        monitor_ctx( this->monitors, this->monitor_count );
    475482
    476483        // Lock all monitors (aggregates the locks them as well)
     
    484491
    485492        //Find the thread to run
    486         thread_desc * signallee = pop_head( this.blocked )->waiting_thread;
     493        thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
    487494        set_owner( monitors, count, signallee );
    488495
    489         LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
     496        LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", this, signallee );
    490497
    491498        //Everything is ready to go to sleep
     
    505512
    506513// Access the user_info of the thread waiting at the front of the queue
    507 uintptr_t front( condition & this ) {
     514uintptr_t front( condition * this ) {
    508515        verifyf( !is_empty(this),
    509516                "Attempt to access user data on an empty condition.\n"
    510517                "Possible cause is not checking if the condition is empty before reading stored data."
    511518        );
    512         return this.blocked.head->user_info;
     519        return this->blocked.head->user_info;
    513520}
    514521
     
    530537        // This statment doesn't have a contiguous list of monitors...
    531538        // Create one!
    532         __lock_size_t max = count_max( mask );
     539        short max = count_max( mask );
    533540        monitor_desc * mon_storage[max];
    534541        __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );
    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);
     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);
    538545
    539546        if(actual_count == 0) return;
     
    562569
    563570                                __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
    564                                 push( mon2dtor->signal_stack, dtor_crit );
     571                                push( &mon2dtor->signal_stack, dtor_crit );
    565572
    566573                                unlock_all( locks, count );
     
    622629        set_mask( monitors, count, mask );
    623630
    624         for( __lock_size_t i = 0; i < count; i++) {
     631        for(int i = 0; i < count; i++) {
    625632                verify( monitors[i]->owner == this_thread );
    626633        }
     
    654661}
    655662
    656 static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) {
     663static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) {
    657664        monitors[0]->owner     = owner;
    658665        monitors[0]->recursion = 1;
    659         for( __lock_size_t i = 1; i < count; i++ ) {
     666        for( int i = 1; i < count; i++ ) {
    660667                monitors[i]->owner     = owner;
    661668                monitors[i]->recursion = 0;
     
    663670}
    664671
    665 static 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++) {
     672static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {
     673        for(int i = 0; i < count; i++) {
    667674                storage[i]->mask = mask;
    668675        }
     
    678685        //Check the signaller stack
    679686        LIB_DEBUG_PRINT_SAFE("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
    680         __condition_criterion_t * urgent = pop( this->signal_stack );
     687        __condition_criterion_t * urgent = pop( &this->signal_stack );
    681688        if( urgent ) {
    682689                //The signaller stack is not empty,
     
    690697        // No signaller thread
    691698        // Get the next thread in the entry_queue
    692         thread_desc * new_owner = pop_head( this->entry_queue );
     699        thread_desc * new_owner = pop_head( &this->entry_queue );
    693700        set_owner( this, new_owner );
    694701
     
    698705static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
    699706        __acceptable_t * it = this->mask.clauses; // Optim
    700         __lock_size_t count = this->mask.size;
     707        int count = this->mask.size;
    701708
    702709        // Check if there are any acceptable functions
     
    707714
    708715        // For all acceptable functions check if this is the current function.
    709         for( __lock_size_t i = 0; i < count; i++, it++ ) {
     716        for( short i = 0; i < count; i++, it++ ) {
    710717                if( *it == group ) {
    711718                        *this->mask.accepted = i;
     
    718725}
    719726
    720 static 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++) {
     727static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
     728        for(int i = 0; i < count; i++) {
    722729                (criteria[i]){ monitors[i], waiter };
    723730        }
    724731
    725         waiter.criteria = criteria;
    726 }
    727 
    728 static 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++) {
     732        waiter->criteria = criteria;
     733}
     734
     735static 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++) {
    730737                (criteria[i]){ monitors[i], waiter };
    731738                LIB_DEBUG_PRINT_SAFE( "Kernel :  target %p = %p\n", criteria[i].target, &criteria[i] );
    732                 push( criteria[i].target->signal_stack, &criteria[i] );
    733         }
    734 
    735         waiter.criteria = criteria;
    736 }
    737 
    738 static 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 
    744 static 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 );
     739                push( &criteria[i].target->signal_stack, &criteria[i] );
     740        }
     741
     742        waiter->criteria = criteria;
     743}
     744
     745static 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
     751static 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 );
    748755                if(locks) locks[i] = l;
    749756        }
    750757}
    751758
    752 static 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 
    758 static 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 
    764 static 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++ ) {
     759static inline void unlock_all( spinlock ** locks, unsigned short count ) {
     760        for( int i = 0; i < count; i++ ) {
     761                unlock( locks[i] );
     762        }
     763}
     764
     765static 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
     771static 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++ ) {
    772773                recursions[i] = ctx[i]->recursion;
    773774                masks[i]      = ctx[i]->mask;
     
    775776}
    776777
    777 static 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 ) {
     778static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {
    784779        lock_all( locks, count );
    785         for( __lock_size_t i = 0; i < count; i++ ) {
     780        for( int i = 0; i < count; i++ ) {
    786781                ctx[i]->recursion = recursions[i];
    787782                ctx[i]->mask      = masks[i];
     
    816811}
    817812
    818 static inline void brand_condition( condition & this ) {
     813static inline void brand_condition( condition * this ) {
    819814        thread_desc * thrd = this_thread;
    820         if( !this.monitors ) {
     815        if( !this->monitors ) {
    821816                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    822817                assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
    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 
    832 static 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;
     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
     827static 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;
    835830
    836831        // For each thread in the entry-queue
    837         for(    thread_desc ** thrd_it = &entry_queue.head;
     832        for(    thread_desc ** thrd_it = &entry_queue->head;
    838833                *thrd_it;
    839834                thrd_it = &(*thrd_it)->next
     
    857852
    858853forall(dtype T | sized( T ))
    859 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) {
     854static inline short insert_unique( T ** array, short & size, T * val ) {
    860855        if( !val ) return size;
    861856
    862         for( __lock_size_t i = 0; i <= size; i++) {
     857        for(int i = 0; i <= size; i++) {
    863858                if( array[i] == val ) return size;
    864859        }
     
    869864}
    870865
    871 static 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++ ) {
     866static inline short count_max( const __waitfor_mask_t & mask ) {
     867        short max = 0;
     868        for( int i = 0; i < mask.size; i++ ) {
    874869                max += mask.clauses[i].size;
    875870        }
     
    877872}
    878873
    879 static 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++ ) {
     874static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {
     875        short size = 0;
     876        for( int i = 0; i < mask.size; i++ ) {
    882877                __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size );
    883                 for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) {
     878                for( int j = 0; j < mask.clauses[i].size; j++) {
    884879                        insert_unique( storage, size, mask.clauses[i].list[j] );
    885880                }
     
    895890}
    896891
    897 void 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;
     892void 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;
    905900        if( head ) {
    906                 this.head = head->next;
     901                this->head = head->next;
    907902                if( !head->next ) {
    908                         this.tail = &this.head;
     903                        this->tail = &this->head;
    909904                }
    910905                head->next = NULL;
Note: See TracChangeset for help on using the changeset viewer.