Ignore:
File:
1 edited

Legend:

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

    rb8116cd rd67cdb7  
    9494                }
    9595                else if( this->owner == thrd) {
    96                         // We already have the monitor, just note how many times we took it
     96                        // We already have the monitor, just not how many times we took it
    9797                        verify( this->recursion > 0 );
    9898                        this->recursion += 1;
     
    127127                unlock( &this->lock );
    128128                return;
    129         }
    130 
    131         static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    132                 // Lock the monitor spinlock, lock_yield to reduce contention
    133                 lock_yield( &this->lock DEBUG_CTX2 );
    134                 thread_desc * thrd = this_thread;
    135 
    136                 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
    137 
    138 
    139                 if( !this->owner ) {
    140                         LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this);
    141 
    142                         // No one has the monitor, just take it
    143                         set_owner( this, thrd );
    144 
    145                         unlock( &this->lock );
    146                         return;
    147                 }
    148                 else if( this->owner == thrd) {
    149                         // We already have the monitor... but where about to destroy it so the nesting will fail
    150                         // Abort!
    151                         abortf("Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.");
    152                 }
    153 
    154                 int count = 1;
    155                 monitor_desc ** monitors = &this;
    156                 __monitor_group_t group = { &this, 1, func };
    157                 if( is_accepted( this, group) ) {
    158                         LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts dtor, block and signal it \n");
    159 
    160                         // Wake the thread that is waiting for this
    161                         __condition_criterion_t * urgent = pop( &this->signal_stack );
    162                         verify( urgent );
    163 
    164                         // Reset mask
    165                         reset_mask( this );
    166 
    167                         // Create the node specific to this wait operation
    168                         wait_ctx_primed( this_thread, 0 )
    169 
    170                         // Some one else has the monitor, wait for him to finish and then run
    171                         BlockInternal( &this->lock, urgent->owner->waiting_thread );
    172 
    173                         // Some one was waiting for us, enter
    174                         set_owner( this, thrd );
    175                 }
    176                 else {
    177                         LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
    178 
    179                         wait_ctx( this_thread, 0 )
    180                         this->dtor_node = &waiter;
    181 
    182                         // Some one else has the monitor, wait in line for it
    183                         append( &this->entry_queue, thrd );
    184                         BlockInternal( &this->lock );
    185 
    186                         // BlockInternal will unlock spinlock, no need to unlock ourselves
    187                         return;
    188                 }
    189 
    190                 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this);
    191 
    192129        }
    193130
     
    221158        }
    222159
    223         // Leave single monitor for the last time
    224         void __leave_dtor_monitor_desc( monitor_desc * this ) {
    225                 LIB_DEBUG_DO(
    226                         if( this_thread != this->owner ) {
    227                                 abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
    228                         }
    229                         if( this->recursion != 1 ) {
    230                                 abortf("Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
    231                         }
    232                 )
    233         }
    234 
    235160        // Leave the thread monitor
    236161        // last routine called by a thread.
     
    285210// Ctor for monitor guard
    286211// Sorts monitors before entering
    287 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
     212void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
    288213        // Store current array
    289214        this.m = m;
     
    321246
    322247        // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");
    323 
    324         // Restore thread context
    325         this_thread->monitors.list = this.prev_mntrs;
    326         this_thread->monitors.size = this.prev_count;
    327         this_thread->monitors.func = this.prev_func;
    328 }
    329 
    330 
    331 // Ctor for monitor guard
    332 // Sorts monitors before entering
    333 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) {
    334         // Store current array
    335         this.m = *m;
    336 
    337         // Save previous thread context
    338         this.prev_mntrs = this_thread->monitors.list;
    339         this.prev_count = this_thread->monitors.size;
    340         this.prev_func  = this_thread->monitors.func;
    341 
    342         // Update thread context (needed for conditions)
    343         this_thread->monitors.list = m;
    344         this_thread->monitors.size = 1;
    345         this_thread->monitors.func = func;
    346 
    347         __enter_monitor_dtor( this.m, func );
    348 }
    349 
    350 
    351 // Dtor for monitor guard
    352 void ^?{}( monitor_dtor_guard_t & this ) {
    353         // Leave the monitors in order
    354         __leave_dtor_monitor_desc( this.m );
    355248
    356249        // Restore thread context
     
    555448                        *mask.accepted = index;
    556449                        if( mask.clauses[index].is_dtor ) {
    557                                 LIB_DEBUG_PRINT_SAFE("Kernel : dtor already there\n");
    558                                 verifyf( mask.clauses[index].size == 1        , "ERROR: Accepted dtor has more than 1 mutex parameter." );
    559 
    560                                 monitor_desc * mon2dtor = mask.clauses[index].list[0];
    561                                 verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." );
    562 
    563                                 __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
    564                                 push( &mon2dtor->signal_stack, dtor_crit );
    565 
    566                                 unlock_all( locks, count );
     450                                #warning case not implemented
    567451                        }
    568452                        else {
Note: See TracChangeset for help on using the changeset viewer.