Changeset 2ab67b9 for src


Ignore:
Timestamp:
May 30, 2017, 7:49:45 AM (7 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
f3fc631f
Parents:
8f61052c (diff), 4a368547 (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' of plg2:software/cfa/cfa-cc

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/monitor

    r8f61052c r2ab67b9  
    5959        unsigned short count;                           //Number of criterions in the criteria
    6060        __condition_node_t * next;                      //Intrusive linked list Next field
     61        uintptr_t user_info;                            //Custom user info accessible before signalling
    6162};
    6263
     
    8586}
    8687
    87 void wait( condition * this );
    88 void signal( condition * this );
    89 void signal_block( condition * this );
     88void wait( condition * this, uintptr_t user_info = 0 );
     89bool signal( condition * this );
     90bool signal_block( condition * this );
     91static inline bool is_empty( condition * this ) { return !this->blocked.head; }
     92uintptr_t front( condition * this );
     93
    9094#endif //MONITOR_H
  • src/libcfa/concurrency/monitor.c

    r8f61052c r2ab67b9  
    137137}
    138138
    139 void debug_break() __attribute__(( noinline ))
    140 {
    141        
     139void ?{}(__condition_node_t * this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
     140        this->waiting_thread = waiting_thread;
     141        this->count = count;
     142        this->next = NULL;
     143        this->user_info = user_info;
     144}
     145
     146void ?{}(__condition_criterion_t * this ) {
     147        this->ready  = false;
     148        this->target = NULL;
     149        this->owner  = NULL;
     150        this->next   = NULL;
     151}
     152
     153void ?{}(__condition_criterion_t * this, monitor_desc * target, __condition_node_t * owner ) {
     154        this->ready  = false;
     155        this->target = target;
     156        this->owner  = owner;
     157        this->next   = NULL;
    142158}
    143159
    144160//-----------------------------------------------------------------------------
    145161// Internal scheduling
    146 void wait( condition * this ) {
     162void wait( condition * this, uintptr_t user_info = 0 ) {
    147163        LIB_DEBUG_PRINT_SAFE("Waiting\n");
    148164
     
    160176        LIB_DEBUG_PRINT_SAFE("count %i\n", count);
    161177
    162         __condition_node_t waiter;
    163         waiter.waiting_thread = this_thread();
    164         waiter.count = count;
    165         waiter.next = NULL;
     178        __condition_node_t waiter = { this_thread(), count, user_info };
    166179
    167180        __condition_criterion_t criteria[count];
    168181        for(int i = 0; i < count; i++) {
    169                 criteria[i].ready  = false;
    170                 criteria[i].target = this->monitors[i];
    171                 criteria[i].owner  = &waiter;
    172                 criteria[i].next   = NULL;
     182                (&criteria[i]){ this->monitors[i], &waiter };
    173183                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    174184        }
     
    202212        ScheduleInternal( locks, count, threads, thread_count );
    203213
    204         debug_break();
    205214        //WE WOKE UP
    206215
     
    212221}
    213222
    214 void signal( condition * this ) {
    215         if( !this->blocked.head ) {
     223bool signal( condition * this ) {
     224        if( is_empty( this ) ) {
    216225                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    217                 return;
     226                return false;
    218227        }
    219228
     
    257266        //Release
    258267        unlock_all( this->monitors, count );
    259 }
    260 
    261 void signal_block( condition * this ) {
     268
     269        return true;
     270}
     271
     272bool signal_block( condition * this ) {
    262273        if( !this->blocked.head ) {
    263274                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    264                 return;
     275                return false;
    265276        }
    266277
     
    276287
    277288        //create creteria
    278         __condition_node_t waiter;
    279         waiter.waiting_thread = this_thread();
    280         waiter.count = count;
    281         waiter.next = NULL;
     289        __condition_node_t waiter = { this_thread(), count, 0 };
    282290
    283291        __condition_criterion_t criteria[count];
    284292        for(int i = 0; i < count; i++) {
     293                (&criteria[i]){ this->monitors[i], &waiter };
    285294                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
    286                 criteria[i].ready  = false;
    287                 criteria[i].owner  = &waiter;
    288                 criteria[i].next   = NULL;
    289                 criteria[i].target = this->monitors[i];
    290295                push( &criteria[i].target->signal_stack, &criteria[i] );
    291296        }
     
    303308
    304309        LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" );
    305         debug_break();
    306310
    307311        //Everything is ready to go to sleep
    308312        ScheduleInternal( locks, count, &signallee, 1 );
    309313
    310         debug_break();
    311314        LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
    312315
     
    315318        restore_recursion( this->monitors, recursions, count );
    316319        unlock_all( locks, count );
     320
     321        return true;
     322}
     323
     324uintptr_t front( condition * this ) {
     325        LIB_DEBUG_DO(
     326                if( is_empty(this) ) {
     327                        abortf( "Attempt to access user data on an empty condition.\n"
     328                    "Possible cause is not checking if the condition is empty before reading stored data." );
     329                }
     330        );
     331        return this->blocked.head->user_info;
    317332}
    318333
  • src/tests/sched-int-block.c

    r8f61052c r2ab67b9  
    1010
    1111monitor global_data_t {
    12         state_t state;
    13         bool ran;
     12        thread_desc * last_thread;
     13        thread_desc * last_signaller;
    1414};
    1515
    1616void ?{} ( global_data_t * this ) {
    17         this->state = BARGE;
     17        this->last_thread = NULL;
     18        this->last_signaller = NULL;
    1819}
    1920
     
    2829//------------------------------------------------------------------------------
    2930void wait_op( global_data_t * mutex a, global_data_t * mutex b, unsigned i ) {
    30         wait( &cond );
    31         a->ran = b->ran = true;
     31        wait( &cond, (uintptr_t)this_thread() );
    3232
    3333        yield( ((unsigned)rand48()) % 10 );
    3434
    35         if(a->state != SIGNAL || b->state != SIGNAL) {
    36                 sout | "ERROR Barging detected" | a->state | b->state | endl;
     35        if(a->last_thread != a->last_signaller || b->last_thread != b->last_signaller ) {
     36                sout | "ERROR Barging detected, expected" | a->last_signaller | b->last_signaller | "got" | a->last_thread | b->last_thread | endl;
    3737                abort();
    3838        }
    3939
    40         a->state = b->state = WAITED;
     40        a->last_thread = b->last_thread = this_thread();
    4141
    4242        yield( ((unsigned)rand48()) % 10 );
     
    5454        yield( ((unsigned)rand48()) % 10 );
    5555
    56         a->ran = b->ran = false;
    57         a->state = b->state = SIGNAL;
     56        a->last_thread = b->last_thread = a->last_signaller = b->last_signaller = this_thread();
    5857
    59         signal_block( &cond );
     58        if( !is_empty( &cond ) ) {
    6059
    61         yield( ((unsigned)rand48()) % 10 );
     60                thread_desc * next = front( &cond );
    6261
    63         assert(a->ran == b->ran);
    64         if(a->ran)
    65         {
    66                 if(a->state != WAITED || b->state != WAITED) {
    67                         sout | "ERROR Barging detected" | a->state | b->state | endl;
     62                if( ! signal_block( &cond ) ) {
     63                        sout | "ERROR expected to be able to signal" | endl;
     64                        abort();
     65                }
     66
     67                yield( ((unsigned)rand48()) % 10 );
     68
     69                if(a->last_thread != next || b->last_thread != next) {
     70                        sout | "ERROR Barging detected, expected" | next | "got" | a->last_thread | b->last_thread | endl;
    6871                        abort();
    6972                }
     
    8184//------------------------------------------------------------------------------
    8285void barge_op( global_data_t * mutex a ) {
    83         a->state = BARGE;
     86        a->last_thread = this_thread();
    8487}
    8588
  • src/tests/sched-int-disjoint.c

    r8f61052c r2ab67b9  
    7878        signal( &cond, a, &data );
    7979
    80         int pauses = (unsigned)rand48() % 10;
    81         for(int i = 0; i < pauses; i++) {
    82                 yield();
    83         }
     80        yield( (unsigned)rand48() % 10 );
    8481
    8582        //This is technically a mutual exclusion violation but the mutex monitor protects us
Note: See TracChangeset for help on using the changeset viewer.