Changeset be3d020


Ignore:
Timestamp:
May 29, 2017, 11:26:03 AM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
ccd349d
Parents:
8c700c1
Message:
  • signal/signal_block now returns true if the queue was not empty
  • wait now supports passing in a user define value
Location:
src/libcfa/concurrency
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/monitor

    r8c700c1 rbe3d020  
    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

    r8c700c1 rbe3d020  
    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
Note: See TracChangeset for help on using the changeset viewer.