Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

File:
1 moved

Legend:

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

    rf9feab8 r90152a4  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 31 14:59:05 2017
    13 // Update Count     : 3
     12// Last Modified On : Fri Mar 30 14:30:26 2018
     13// Update Count     : 9
    1414//
    1515
    16 #include "monitor"
    17 
    18 #include <stdlib>
     16#include "monitor.hfa"
     17
     18#include <stdlib.hfa>
    1919#include <inttypes.h>
    2020
    21 #include "kernel_private.h"
    22 
    23 #include "bits/algorithms.h"
     21#include "kernel_private.hfa"
     22
     23#include "bits/algorithm.hfa"
    2424
    2525//-----------------------------------------------------------------------------
     
    5353static inline __lock_size_t aggregate    ( monitor_desc * storage [], const __waitfor_mask_t & mask );
    5454
    55 #ifndef __CFA_LOCK_NO_YIELD
    56 #define DO_LOCK lock_yield
    57 #else
    58 #define DO_LOCK lock
    59 #endif
    60 
    6155//-----------------------------------------------------------------------------
    6256// Useful defines
     
    9084        static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
    9185                // Lock the monitor spinlock
    92                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    93                 thread_desc * thrd = this_thread;
    94 
    95                 __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     86                lock( this->lock __cfaabi_dbg_ctx2 );
     87                // Interrupts disable inside critical section
     88                thread_desc * thrd = kernelTLS.this_thread;
     89
     90                __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    9691
    9792                if( !this->owner ) {
     
    9994                        set_owner( this, thrd );
    10095
    101                         __cfaabi_dbg_print_safe("Kernel :  mon is free \n");
     96                        __cfaabi_dbg_print_safe( "Kernel :  mon is free \n" );
    10297                }
    10398                else if( this->owner == thrd) {
     
    105100                        this->recursion += 1;
    106101
    107                         __cfaabi_dbg_print_safe("Kernel :  mon already owned \n");
     102                        __cfaabi_dbg_print_safe( "Kernel :  mon already owned \n" );
    108103                }
    109104                else if( is_accepted( this, group) ) {
     
    114109                        reset_mask( this );
    115110
    116                         __cfaabi_dbg_print_safe("Kernel :  mon accepts \n");
     111                        __cfaabi_dbg_print_safe( "Kernel :  mon accepts \n" );
    117112                }
    118113                else {
    119                         __cfaabi_dbg_print_safe("Kernel :  blocking \n");
     114                        __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
    120115
    121116                        // Some one else has the monitor, wait in line for it
    122117                        append( this->entry_queue, thrd );
     118
    123119                        BlockInternal( &this->lock );
    124120
    125                         __cfaabi_dbg_print_safe("Kernel : %10p Entered  mon %p\n", thrd, this);
     121                        __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
    126122
    127123                        // BlockInternal will unlock spinlock, no need to unlock ourselves
     
    129125                }
    130126
    131                 __cfaabi_dbg_print_safe("Kernel : %10p Entered  mon %p\n", thrd, this);
     127                __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
    132128
    133129                // Release the lock and leave
     
    138134        static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    139135                // Lock the monitor spinlock
    140                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    141                 thread_desc * thrd = this_thread;
    142 
    143                 __cfaabi_dbg_print_safe("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
     136                lock( this->lock __cfaabi_dbg_ctx2 );
     137                // Interrupts disable inside critical section
     138                thread_desc * thrd = kernelTLS.this_thread;
     139
     140                __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
    144141
    145142
    146143                if( !this->owner ) {
    147                         __cfaabi_dbg_print_safe("Kernel : Destroying free mon %p\n", this);
     144                        __cfaabi_dbg_print_safe( "Kernel : Destroying free mon %p\n", this);
    148145
    149146                        // No one has the monitor, just take it
     
    156153                        // We already have the monitor... but where about to destroy it so the nesting will fail
    157154                        // Abort!
    158                         abortf("Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.");
     155                        abort( "Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.", this, thrd->self_cor.name, thrd );
    159156                }
    160157
     
    163160                __monitor_group_t group = { &this, 1, func };
    164161                if( is_accepted( this, group) ) {
    165                         __cfaabi_dbg_print_safe("Kernel :  mon accepts dtor, block and signal it \n");
     162                        __cfaabi_dbg_print_safe( "Kernel :  mon accepts dtor, block and signal it \n" );
    166163
    167164                        // Wake the thread that is waiting for this
     
    173170
    174171                        // Create the node specific to this wait operation
    175                         wait_ctx_primed( this_thread, 0 )
     172                        wait_ctx_primed( thrd, 0 )
    176173
    177174                        // Some one else has the monitor, wait for him to finish and then run
     
    182179                }
    183180                else {
    184                         __cfaabi_dbg_print_safe("Kernel :  blocking \n");
    185 
    186                         wait_ctx( this_thread, 0 )
     181                        __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
     182
     183                        wait_ctx( thrd, 0 )
    187184                        this->dtor_node = &waiter;
    188185
     
    195192                }
    196193
    197                 __cfaabi_dbg_print_safe("Kernel : Destroying %p\n", this);
     194                __cfaabi_dbg_print_safe( "Kernel : Destroying %p\n", this);
    198195
    199196        }
     
    201198        // Leave single monitor
    202199        void __leave_monitor_desc( monitor_desc * this ) {
    203                 // Lock the monitor spinlock, DO_LOCK to reduce contention
    204                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
    205 
    206                 __cfaabi_dbg_print_safe("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
    207 
    208                 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this );
     200                // Lock the monitor spinlock
     201                lock( this->lock __cfaabi_dbg_ctx2 );
     202
     203                __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", kernelTLS.this_thread, this, this->owner);
     204
     205                verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
    209206
    210207                // Leaving a recursion level, decrement the counter
     
    214211                // it means we don't need to do anything
    215212                if( this->recursion != 0) {
    216                         __cfaabi_dbg_print_safe("Kernel :  recursion still %d\n", this->recursion);
     213                        __cfaabi_dbg_print_safe( "Kernel :  recursion still %d\n", this->recursion);
    217214                        unlock( this->lock );
    218215                        return;
     
    232229        void __leave_dtor_monitor_desc( monitor_desc * this ) {
    233230                __cfaabi_dbg_debug_do(
    234                         if( this_thread != this->owner ) {
    235                                 abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
     231                        if( TL_GET( this_thread ) != this->owner ) {
     232                                abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);
    236233                        }
    237234                        if( this->recursion != 1 ) {
    238                                 abortf("Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
     235                                abort( "Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
    239236                        }
    240237                )
     
    248245
    249246                // Lock the monitor now
    250                 DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
     247                lock( this->lock __cfaabi_dbg_ctx2 );
    251248
    252249                disable_interrupts();
     
    261258                // If we haven't left the last level of recursion
    262259                // it must mean there is an error
    263                 if( this->recursion != 0) { abortf("Thread internal monitor has unbalanced recursion"); }
     260                if( this->recursion != 0) { abort( "Thread internal monitor has unbalanced recursion" ); }
    264261
    265262                // Fetch the next thread, can be null
     
    294291// Sorts monitors before entering
    295292void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
     293        thread_desc * thrd = TL_GET( this_thread );
     294
    296295        // Store current array
    297296        this.m = m;
    298297        this.count = count;
    299298
    300         // Sort monitors based on address -> TODO use a sort specialized for small numbers
     299        // Sort monitors based on address
    301300        __libcfa_small_sort(this.m, count);
    302301
    303302        // Save previous thread context
    304         this.prev = this_thread->monitors;
     303        this.prev = thrd->monitors;
    305304
    306305        // Update thread context (needed for conditions)
    307         (this_thread->monitors){m, count, func};
    308 
    309         // __cfaabi_dbg_print_safe("MGUARD : enter %d\n", count);
     306        (thrd->monitors){m, count, func};
     307
     308        // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count);
    310309
    311310        // Enter the monitors in order
     
    313312        enter( group );
    314313
    315         // __cfaabi_dbg_print_safe("MGUARD : entered\n");
     314        // __cfaabi_dbg_print_safe( "MGUARD : entered\n" );
    316315}
    317316
     
    319318// Dtor for monitor guard
    320319void ^?{}( monitor_guard_t & this ) {
    321         // __cfaabi_dbg_print_safe("MGUARD : leaving %d\n", this.count);
     320        // __cfaabi_dbg_print_safe( "MGUARD : leaving %d\n", this.count);
    322321
    323322        // Leave the monitors in order
    324323        leave( this.m, this.count );
    325324
    326         // __cfaabi_dbg_print_safe("MGUARD : left\n");
     325        // __cfaabi_dbg_print_safe( "MGUARD : left\n" );
    327326
    328327        // Restore thread context
    329         this_thread->monitors = this.prev;
     328        TL_GET( this_thread )->monitors = this.prev;
    330329}
    331330
     
    333332// Sorts monitors before entering
    334333void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
     334        // optimization
     335        thread_desc * thrd = TL_GET( this_thread );
     336
    335337        // Store current array
    336338        this.m = *m;
    337339
    338340        // Save previous thread context
    339         this.prev = this_thread->monitors;
     341        this.prev = thrd->monitors;
    340342
    341343        // Update thread context (needed for conditions)
    342         (this_thread->monitors){m, 1, func};
     344        (thrd->monitors){m, 1, func};
    343345
    344346        __enter_monitor_dtor( this.m, func );
     
    351353
    352354        // Restore thread context
    353         this_thread->monitors = this.prev;
     355        TL_GET( this_thread )->monitors = this.prev;
    354356}
    355357
     
    363365}
    364366
    365 void ?{}(__condition_criterion_t & this ) {
    366         this.ready  = false;
    367         this.target = NULL;
    368         this.owner  = NULL;
    369         this.next   = NULL;
     367void ?{}(__condition_criterion_t & this ) with( this ) {
     368        ready  = false;
     369        target = NULL;
     370        owner  = NULL;
     371        next   = NULL;
    370372}
    371373
     
    391393
    392394        // Create the node specific to this wait operation
    393         wait_ctx( this_thread, user_info );
     395        wait_ctx( TL_GET( this_thread ), user_info );
    394396
    395397        // Append the current wait operation to the ones already queued on the condition
     
    430432        //Some more checking in debug
    431433        __cfaabi_dbg_debug_do(
    432                 thread_desc * this_thrd = this_thread;
     434                thread_desc * this_thrd = TL_GET( this_thread );
    433435                if ( this.monitor_count != this_thrd->monitors.size ) {
    434                         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                        abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size );
    435437                }
    436438
    437439                for(int i = 0; i < this.monitor_count; i++) {
    438440                        if ( this.monitors[i] != this_thrd->monitors[i] ) {
    439                                 abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors[i] );
     441                                abort( "Signal on condition %p made with different monitor, expected %p got %p", &this, this.monitors[i], this_thrd->monitors[i] );
    440442                        }
    441443                }
     
    476478        lock_all( monitors, locks, count );
    477479
     480
    478481        // Create the node specific to this wait operation
    479         wait_ctx_primed( this_thread, 0 )
     482        wait_ctx_primed( kernelTLS.this_thread, 0 )
    480483
    481484        //save contexts
     
    534537        __lock_size_t actual_count = aggregate( mon_storage, mask );
    535538
    536         __cfaabi_dbg_print_buffer_decl( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);
     539        __cfaabi_dbg_print_buffer_decl( "Kernel : waitfor %"PRIdFAST16" (s: %"PRIdFAST16", m: %"PRIdFAST16")\n", actual_count, mask.size, (__lock_size_t)max);
    537540
    538541        if(actual_count == 0) return;
    539542
    540         __cfaabi_dbg_print_buffer_local( "Kernel : waitfor internal proceeding\n");
     543        __cfaabi_dbg_print_buffer_local( "Kernel : waitfor internal proceeding\n" );
    541544
    542545        // Create storage for monitor context
     
    555558                        __acceptable_t& accepted = mask[index];
    556559                        if( accepted.is_dtor ) {
    557                                 __cfaabi_dbg_print_buffer_local( "Kernel : dtor already there\n");
     560                                __cfaabi_dbg_print_buffer_local( "Kernel : dtor already there\n" );
    558561                                verifyf( accepted.size == 1,  "ERROR: Accepted dtor has more than 1 mutex parameter." );
    559562
     
    567570                        }
    568571                        else {
    569                                 __cfaabi_dbg_print_buffer_local( "Kernel : thread present, baton-passing\n");
     572                                __cfaabi_dbg_print_buffer_local( "Kernel : thread present, baton-passing\n" );
    570573
    571574                                // Create the node specific to this wait operation
    572                                 wait_ctx_primed( this_thread, 0 );
     575                                wait_ctx_primed( kernelTLS.this_thread, 0 );
    573576
    574577                                // Save monitor states
    575578                                monitor_save;
    576579
    577                                 __cfaabi_dbg_print_buffer_local( "Kernel :  baton of %d monitors : ", count );
     580                                __cfaabi_dbg_print_buffer_local( "Kernel :  baton of %"PRIdFAST16" monitors : ", count );
    578581                                #ifdef __CFA_DEBUG_PRINT__
    579582                                        for( int i = 0; i < count; i++) {
     
    581584                                        }
    582585                                #endif
    583                                 __cfaabi_dbg_print_buffer_local( "\n");
     586                                __cfaabi_dbg_print_buffer_local( "\n" );
    584587
    585588                                // Set the owners to be the next thread
     
    592595                                monitor_restore;
    593596
    594                                 __cfaabi_dbg_print_buffer_local( "Kernel : thread present, returned\n");
     597                                __cfaabi_dbg_print_buffer_local( "Kernel : thread present, returned\n" );
    595598                        }
    596599
     
    602605
    603606        if( duration == 0 ) {
    604                 __cfaabi_dbg_print_buffer_local( "Kernel : non-blocking, exiting\n");
     607                __cfaabi_dbg_print_buffer_local( "Kernel : non-blocking, exiting\n" );
    605608
    606609                unlock_all( locks, count );
     
    611614
    612615
    613         verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");
    614 
    615         __cfaabi_dbg_print_buffer_local( "Kernel : blocking waitfor\n");
     616        verifyf( duration < 0, "Timeout on waitfor statments not supported yet." );
     617
     618        __cfaabi_dbg_print_buffer_local( "Kernel : blocking waitfor\n" );
    616619
    617620        // Create the node specific to this wait operation
    618         wait_ctx_primed( this_thread, 0 );
     621        wait_ctx_primed( kernelTLS.this_thread, 0 );
    619622
    620623        monitor_save;
     
    622625
    623626        for( __lock_size_t i = 0; i < count; i++) {
    624                 verify( monitors[i]->owner == this_thread );
     627                verify( monitors[i]->owner == kernelTLS.this_thread );
    625628        }
    626629
     
    635638        monitor_restore;
    636639
    637         __cfaabi_dbg_print_buffer_local( "Kernel : exiting\n");
     640        __cfaabi_dbg_print_buffer_local( "Kernel : exiting\n" );
    638641
    639642        __cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted);
     
    644647
    645648static inline void set_owner( monitor_desc * this, thread_desc * owner ) {
    646         // __cfaabi_dbg_print_safe("Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
     649        // __cfaabi_dbg_print_safe( "Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
    647650
    648651        //Pass the monitor appropriately
     
    676679static inline thread_desc * next_thread( monitor_desc * this ) {
    677680        //Check the signaller stack
    678         __cfaabi_dbg_print_safe("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
     681        __cfaabi_dbg_print_safe( "Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
    679682        __condition_criterion_t * urgent = pop( this->signal_stack );
    680683        if( urgent ) {
     
    737740static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) {
    738741        for( __lock_size_t i = 0; i < count; i++ ) {
    739                 DO_LOCK( *locks[i] __cfaabi_dbg_ctx2 );
     742                lock( *locks[i] __cfaabi_dbg_ctx2 );
    740743        }
    741744}
     
    744747        for( __lock_size_t i = 0; i < count; i++ ) {
    745748                __spinlock_t * l = &source[i]->lock;
    746                 DO_LOCK( *l __cfaabi_dbg_ctx2 );
     749                lock( *l __cfaabi_dbg_ctx2 );
    747750                if(locks) locks[i] = l;
    748751        }
     
    816819
    817820static inline void brand_condition( condition & this ) {
    818         thread_desc * thrd = this_thread;
     821        thread_desc * thrd = TL_GET( this_thread );
    819822        if( !this.monitors ) {
    820                 // __cfaabi_dbg_print_safe("Branding\n");
     823                // __cfaabi_dbg_print_safe( "Branding\n" );
    821824                assertf( thrd->monitors.data != NULL, "No current monitor to brand condition %p", thrd->monitors.data );
    822825                this.monitor_count = thrd->monitors.size;
Note: See TracChangeset for help on using the changeset viewer.