Ignore:
File:
1 edited

Legend:

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

    rf2b12406 r4aa2fb2  
    1919#include <stdlib>
    2020
     21#include "kernel_private.h"
    2122#include "libhdr.h"
    22 #include "kernel_private.h"
    2323
    2424//-----------------------------------------------------------------------------
     
    4444
    4545extern "C" {
    46         void __enter_monitor_desc( monitor_desc * this ) {
    47                 lock_yield( &this->lock DEBUG_CTX2 );
    48                 thread_desc * thrd = this_thread;
    49 
    50                 // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     46        void __enter_monitor_desc(monitor_desc * this) {
     47                lock( &this->lock );
     48                thread_desc * thrd = this_thread();
     49
     50                LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    5151
    5252                if( !this->owner ) {
     
    6262                        //Some one else has the monitor, wait in line for it
    6363                        append( &this->entry_queue, thrd );
    64                         // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    65                         BlockInternal( &this->lock );
    66 
    67                         //BlockInternal will unlock spinlock, no need to unlock ourselves
    68                         return;
     64                        LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
     65                        ScheduleInternal( &this->lock );
     66
     67                        //ScheduleInternal will unlock spinlock, no need to unlock ourselves
     68                        return; 
    6969                }
    7070
     
    7575        // leave pseudo code :
    7676        //      TODO
    77         void __leave_monitor_desc( monitor_desc * this ) {
    78                 lock_yield( &this->lock DEBUG_CTX2 );
    79 
    80                 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);
    81                 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
     77        void __leave_monitor_desc(monitor_desc * this) {
     78                lock( &this->lock );
     79
     80                LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     81                verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion );
    8282
    8383                //Leaving a recursion level, decrement the counter
     
    9696                unlock( &this->lock );
    9797
    98                 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
     98                LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
    9999
    100100                //We need to wake-up the thread
    101                 WakeThread( new_owner );
    102         }
    103 
    104         void __leave_thread_monitor( thread_desc * thrd ) {
    105                 monitor_desc * this = &thrd->mon;
    106                 lock_yield( &this->lock DEBUG_CTX2 );
    107 
    108                 disable_interrupts();
    109 
    110                 thrd->cor.state = Halted;
    111 
    112                 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
    113 
    114                 //Leaving a recursion level, decrement the counter
    115                 this->recursion -= 1;
    116 
    117                 //If we haven't left the last level of recursion
    118                 //it means we don't need to do anything
    119                 if( this->recursion != 0) {
    120                         unlock( &this->lock );
    121                         return;
    122                 }
    123 
    124                 thread_desc * new_owner = next_thread( this );
    125 
    126                 LeaveThread( &this->lock, new_owner );
     101                ScheduleThread( new_owner );
    127102        }
    128103}
     
    146121        enter( this->m, this->count );
    147122
    148         this->prev_mntrs = this_thread->current_monitors;
    149         this->prev_count = this_thread->current_monitor_count;
    150 
    151         this_thread->current_monitors      = m;
    152         this_thread->current_monitor_count = count;
     123        this->prev_mntrs = this_thread()->current_monitors;
     124        this->prev_count = this_thread()->current_monitor_count;
     125
     126        this_thread()->current_monitors      = m;
     127        this_thread()->current_monitor_count = count;
    153128}
    154129
     
    156131        leave( this->m, this->count );
    157132
    158         this_thread->current_monitors      = this->prev_mntrs;
    159         this_thread->current_monitor_count = this->prev_count;
     133        this_thread()->current_monitors      = this->prev_mntrs;
     134        this_thread()->current_monitor_count = this->prev_count;
    160135}
    161136
     
    184159// Internal scheduling
    185160void wait( condition * this, uintptr_t user_info = 0 ) {
    186         // LIB_DEBUG_PRINT_SAFE("Waiting\n");
     161        LIB_DEBUG_PRINT_SAFE("Waiting\n");
    187162
    188163        brand_condition( this );
     
    195170        unsigned short count = this->monitor_count;
    196171        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    197         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    198 
    199         // LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    200 
    201         __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };
     172        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
     173
     174        LIB_DEBUG_PRINT_SAFE("count %i\n", count);
     175
     176        __condition_node_t waiter = { this_thread(), count, user_info };
    202177
    203178        __condition_criterion_t criteria[count];
    204179        for(int i = 0; i < count; i++) {
    205180                (&criteria[i]){ this->monitors[i], &waiter };
    206                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     181                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    207182        }
    208183
     
    226201        }
    227202
    228         // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     203        LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    229204        for(int i = 0; i < thread_count; i++) {
    230                 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    231         }
    232         // LIB_DEBUG_PRINT_SAFE("\n");
     205                LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     206        }
     207        LIB_DEBUG_PRINT_SAFE("\n");
    233208
    234209        // Everything is ready to go to sleep
    235         BlockInternal( locks, count, threads, thread_count );
     210        ScheduleInternal( locks, count, threads, thread_count );
    236211
    237212
     
    247222bool signal( condition * this ) {
    248223        if( is_empty( this ) ) {
    249                 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     224                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    250225                return false;
    251226        }
     
    256231
    257232        unsigned short count = this->monitor_count;
    258 
     233       
    259234        //Some more checking in debug
    260235        LIB_DEBUG_DO(
    261                 thread_desc * this_thrd = this_thread;
     236                thread_desc * this_thrd = this_thread();
    262237                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    263238                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
     
    273248        //Lock all the monitors
    274249        lock_all( this->monitors, NULL, count );
    275         // LIB_DEBUG_PRINT_SAFE("Signalling");
     250        LIB_DEBUG_PRINT_SAFE("Signalling");
    276251
    277252        //Pop the head of the waiting queue
     
    281256        for(int i = 0; i < count; i++) {
    282257                __condition_criterion_t * crit = &node->criteria[i];
    283                 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     258                LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    284259                assert( !crit->ready );
    285260                push( &crit->target->signal_stack, crit );
    286261        }
    287262
    288         // LIB_DEBUG_PRINT_SAFE("\n");
     263        LIB_DEBUG_PRINT_SAFE("\n");
    289264
    290265        //Release
     
    306281        unsigned short count = this->monitor_count;
    307282        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    308         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
     283        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
    309284
    310285        lock_all( this->monitors, locks, count );
    311286
    312287        //create creteria
    313         __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
     288        __condition_node_t waiter = { this_thread(), count, 0 };
    314289
    315290        __condition_criterion_t criteria[count];
    316291        for(int i = 0; i < count; i++) {
    317292                (&criteria[i]){ this->monitors[i], &waiter };
    318                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     293                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    319294                push( &criteria[i].target->signal_stack, &criteria[i] );
    320295        }
     
    334309
    335310        //Everything is ready to go to sleep
    336         BlockInternal( locks, count, &signallee, 1 );
     311        ScheduleInternal( locks, count, &signallee, 1 );
    337312
    338313
     
    350325
    351326uintptr_t front( condition * this ) {
    352         verifyf( !is_empty(this),
     327        verifyf( !is_empty(this), 
    353328                "Attempt to access user data on an empty condition.\n"
    354329                "Possible cause is not checking if the condition is empty before reading stored data."
     
    360335// Internal scheduling
    361336void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    362         // thread_desc * this = this_thread;
     337        // thread_desc * this = this_thread();
    363338
    364339        // unsigned short count = this->current_monitor_count;
    365340        // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    366         // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to BlockInternal
     341        // spinlock *   locks     [ count ];            //We need to pass-in an array of locks to ScheduleInternal
    367342
    368343        // lock_all( this->current_monitors, locks, count );
     
    373348
    374349        // // // Everything is ready to go to sleep
    375         // // BlockInternal( locks, count, threads, thread_count );
     350        // // ScheduleInternal( locks, count, threads, thread_count );
    376351
    377352
     
    418393static inline void lock_all( spinlock ** locks, unsigned short count ) {
    419394        for( int i = 0; i < count; i++ ) {
    420                 lock_yield( locks[i] DEBUG_CTX2 );
     395                lock( locks[i] );
    421396        }
    422397}
     
    425400        for( int i = 0; i < count; i++ ) {
    426401                spinlock * l = &source[i]->lock;
    427                 lock_yield( l DEBUG_CTX2 );
     402                lock( l );
    428403                if(locks) locks[i] = l;
    429404        }
     
    468443        for(    int i = 0; i < count; i++ ) {
    469444
    470                 // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
     445                LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
    471446                if( &criteria[i] == target ) {
    472447                        criteria[i].ready = true;
    473                         // LIB_DEBUG_PRINT_SAFE( "True\n" );
     448                        LIB_DEBUG_PRINT_SAFE( "True\n" );
    474449                }
    475450
     
    477452        }
    478453
    479         // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     454        LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    480455        return ready2run ? node->waiting_thread : NULL;
    481456}
    482457
    483458static inline void brand_condition( condition * this ) {
    484         thread_desc * thrd = this_thread;
     459        thread_desc * thrd = this_thread();
    485460        if( !this->monitors ) {
    486                 // LIB_DEBUG_PRINT_SAFE("Branding\n");
     461                LIB_DEBUG_PRINT_SAFE("Branding\n");
    487462                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    488463                this->monitor_count = thrd->current_monitor_count;
Note: See TracChangeset for help on using the changeset viewer.