Changeset e426c6f


Ignore:
Timestamp:
Mar 26, 2026, 10:40:39 PM (3 hours ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Parents:
6cbc5a62
Message:

fix signal_block on empty condition queue

File:
1 edited

Legend:

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

    r6cbc5a62 re426c6f  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Nov  4 22:03:41 2025
    13 // Update Count     : 82
     12// Last Modified On : Thu Mar 26 22:37:42 2026
     13// Update Count     : 91
    1414//
    1515
     
    493493}
    494494
    495 bool signal( condition & this ) libcfa_public {
    496         if ( empty( this ) ) { return false; }
    497 
    498         //Check that everything is as expected
    499         verify( this.monitors );
    500         verify( this.monitor_count != 0 );
    501 
    502         //Some more checking in debug
    503         __cfaabi_dbg_debug_do(
     495bool signal( condition & this ) libcfa_public with( this ) {
     496  if ( empty( this ) ) { return false; }
     497
     498        verifyf( monitors != 0p, "Waiting with no monitors (%p)", monitors );
     499        verifyf( monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", monitor_count );
     500
     501        __cfaabi_dbg_debug_do(                                                          // more checking in debug
    504502                thread$ * this_thrd = active_thread();
    505                 if ( this.monitor_count != this_thrd->monitors.size ) {
    506                         abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size );
    507                 }
    508 
    509                 for ( i; this.monitor_count ) {
    510                         if ( this.monitors[i] != this_thrd->monitors[i] ) {
    511                                 abort( "Signal on condition %p made with different monitor, expected %p got %p", &this, this.monitors[i], this_thrd->monitors[i] );
    512                         }
    513                 }
     503                if ( monitor_count != this_thrd->monitors.size ) {
     504                        abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi",
     505                                   &this, monitor_count, this_thrd->monitors.size );
     506                } // if
     507
     508                for ( i; monitor_count ) {
     509                        if ( monitors[i] != this_thrd->monitors[i] ) {
     510                                abort( "Signal on condition %p made with different monitor, expected %p got %p",
     511                                           &this, monitors[i], this_thrd->monitors[i] );
     512                        } // if
     513                } // for
    514514        );
    515515
    516         __lock_size_t count = this.monitor_count;
    517 
    518         // Lock all monitors
    519         lock_all( this.monitors, 0p, count );
    520 
    521         //Pop the head of the waiting queue
    522         __condition_node_t * node = pop_head( this.blocked );
    523 
    524         //Add the thread to the proper AS stack
    525         for ( i; count ) {
     516        __lock_size_t count = monitor_count;
     517        lock_all( monitors, 0p, count );                                        // lock all monitors
     518        __condition_node_t * node = pop_head( blocked );        // pop head of waiting queue
     519
     520        for ( i; count ) {                                                                      // add threads to the proper AS stack
    526521                __condition_criterion_t * crit = &node->criteria[i];
    527522                assert( ! crit->ready );
    528523                push( crit->target->signal_stack, crit );
    529         }
    530 
    531         //Release
    532         unlock_all( this.monitors, count );
    533 
     524        } // for
     525
     526        unlock_all( monitors, count );                                          // release
    534527        return true;
    535 }
     528} // signal
    536529
    537530bool signal_block( condition & this ) libcfa_public {
    538         if ( ! this.blocked.head ) { return false; }
    539 
    540         //Check that everything is as expected
     531  if ( empty( this ) ) { return false; }
     532
    541533        verifyf( this.monitors != 0p, "Waiting with no monitors (%p)", this.monitors );
    542534        verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count );
     
    551543        wait_ctx_primed( active_thread(), 0 )
    552544
    553         //save contexts
    554         monitor_save;
     545        monitor_save;                                                                           // save contexts
    555546
    556547        //Find the thread to run
     
    560551        __cfaabi_dbg_print_buffer_decl( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
    561552
    562         // unlock all the monitors
    563         unlock_all( locks, count );
    564 
    565         // unpark the thread we signalled
    566         unpark( signallee );
    567 
    568         //Everything is ready to go to sleep
    569         park();
    570 
    571         // WE WOKE UP
     553        unlock_all( locks, count );                                                     // unlock all the monitors
     554        unpark( signallee );                                                            // unpark the thread we signalled
     555        park();                                                                                         // everything is ready to go to sleep
     556
     557        // WOKE UP
    572558
    573559        __cfaabi_dbg_print_buffer_local( "Kernel : signal_block returned\n" );
    574560
    575         //We are back, restore the masks and recursions
    576         monitor_restore;
     561        monitor_restore;                                                                        // restore the masks and recursions
    577562
    578563        return true;
    579 }
     564} // signal_block
    580565
    581566// Access the user_info of the thread waiting at the front of the queue
Note: See TracChangeset for help on using the changeset viewer.