Ignore:
File:
1 edited

Legend:

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

    rb227f68 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                 //We can now let other threads in safely
    127                 unlock( &this->lock );
    128 
    129                 //We need to wake-up the thread
    130                 if( new_owner) ScheduleThread( new_owner );
     101                ScheduleThread( new_owner );
    131102        }
    132103}
     
    150121        enter( this->m, this->count );
    151122
    152         this->prev_mntrs = this_thread->current_monitors;
    153         this->prev_count = this_thread->current_monitor_count;
    154 
    155         this_thread->current_monitors      = m;
    156         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;
    157128}
    158129
     
    160131        leave( this->m, this->count );
    161132
    162         this_thread->current_monitors      = this->prev_mntrs;
    163         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;
    164135}
    165136
     
    188159// Internal scheduling
    189160void wait( condition * this, uintptr_t user_info = 0 ) {
    190         // LIB_DEBUG_PRINT_SAFE("Waiting\n");
     161        LIB_DEBUG_PRINT_SAFE("Waiting\n");
    191162
    192163        brand_condition( this );
     
    199170        unsigned short count = this->monitor_count;
    200171        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    201         spinlock *   locks     [ count ];               //We need to pass-in an array of locks to BlockInternal
    202 
    203         // LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    204 
    205         __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 };
    206177
    207178        __condition_criterion_t criteria[count];
    208179        for(int i = 0; i < count; i++) {
    209180                (&criteria[i]){ this->monitors[i], &waiter };
    210                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     181                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    211182        }
    212183
     
    230201        }
    231202
    232         // LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     203        LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    233204        for(int i = 0; i < thread_count; i++) {
    234                 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
    235         }
    236         // LIB_DEBUG_PRINT_SAFE("\n");
     205                LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     206        }
     207        LIB_DEBUG_PRINT_SAFE("\n");
    237208
    238209        // Everything is ready to go to sleep
    239         BlockInternal( locks, count, threads, thread_count );
     210        ScheduleInternal( locks, count, threads, thread_count );
    240211
    241212
     
    251222bool signal( condition * this ) {
    252223        if( is_empty( this ) ) {
    253                 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     224                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    254225                return false;
    255226        }
     
    260231
    261232        unsigned short count = this->monitor_count;
    262 
     233       
    263234        //Some more checking in debug
    264235        LIB_DEBUG_DO(
    265                 thread_desc * this_thrd = this_thread;
     236                thread_desc * this_thrd = this_thread();
    266237                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    267238                        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 );
     
    277248        //Lock all the monitors
    278249        lock_all( this->monitors, NULL, count );
    279         // LIB_DEBUG_PRINT_SAFE("Signalling");
     250        LIB_DEBUG_PRINT_SAFE("Signalling");
    280251
    281252        //Pop the head of the waiting queue
     
    285256        for(int i = 0; i < count; i++) {
    286257                __condition_criterion_t * crit = &node->criteria[i];
    287                 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     258                LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    288259                assert( !crit->ready );
    289260                push( &crit->target->signal_stack, crit );
    290261        }
    291262
    292         // LIB_DEBUG_PRINT_SAFE("\n");
     263        LIB_DEBUG_PRINT_SAFE("\n");
    293264
    294265        //Release
     
    310281        unsigned short count = this->monitor_count;
    311282        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    312         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
    313284
    314285        lock_all( this->monitors, locks, count );
    315286
    316287        //create creteria
    317         __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
     288        __condition_node_t waiter = { this_thread(), count, 0 };
    318289
    319290        __condition_criterion_t criteria[count];
    320291        for(int i = 0; i < count; i++) {
    321292                (&criteria[i]){ this->monitors[i], &waiter };
    322                 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     293                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    323294                push( &criteria[i].target->signal_stack, &criteria[i] );
    324295        }
     
    338309
    339310        //Everything is ready to go to sleep
    340         BlockInternal( locks, count, &signallee, 1 );
     311        ScheduleInternal( locks, count, &signallee, 1 );
    341312
    342313
     
    354325
    355326uintptr_t front( condition * this ) {
    356         verifyf( !is_empty(this),
     327        verifyf( !is_empty(this), 
    357328                "Attempt to access user data on an empty condition.\n"
    358329                "Possible cause is not checking if the condition is empty before reading stored data."
     
    364335// Internal scheduling
    365336void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
    366         // thread_desc * this = this_thread;
     337        // thread_desc * this = this_thread();
    367338
    368339        // unsigned short count = this->current_monitor_count;
    369340        // unsigned int recursions[ count ];            //Save the current recursion levels to restore them later
    370         // 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
    371342
    372343        // lock_all( this->current_monitors, locks, count );
     
    377348
    378349        // // // Everything is ready to go to sleep
    379         // // BlockInternal( locks, count, threads, thread_count );
     350        // // ScheduleInternal( locks, count, threads, thread_count );
    380351
    381352
     
    422393static inline void lock_all( spinlock ** locks, unsigned short count ) {
    423394        for( int i = 0; i < count; i++ ) {
    424                 lock_yield( locks[i] DEBUG_CTX2 );
     395                lock( locks[i] );
    425396        }
    426397}
     
    429400        for( int i = 0; i < count; i++ ) {
    430401                spinlock * l = &source[i]->lock;
    431                 lock_yield( l DEBUG_CTX2 );
     402                lock( l );
    432403                if(locks) locks[i] = l;
    433404        }
     
    472443        for(    int i = 0; i < count; i++ ) {
    473444
    474                 // 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 );
    475446                if( &criteria[i] == target ) {
    476447                        criteria[i].ready = true;
    477                         // LIB_DEBUG_PRINT_SAFE( "True\n" );
     448                        LIB_DEBUG_PRINT_SAFE( "True\n" );
    478449                }
    479450
     
    481452        }
    482453
    483         // LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     454        LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
    484455        return ready2run ? node->waiting_thread : NULL;
    485456}
    486457
    487458static inline void brand_condition( condition * this ) {
    488         thread_desc * thrd = this_thread;
     459        thread_desc * thrd = this_thread();
    489460        if( !this->monitors ) {
    490                 // LIB_DEBUG_PRINT_SAFE("Branding\n");
     461                LIB_DEBUG_PRINT_SAFE("Branding\n");
    491462                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
    492463                this->monitor_count = thrd->current_monitor_count;
Note: See TracChangeset for help on using the changeset viewer.