Ignore:
Timestamp:
Mar 28, 2017, 1:03:01 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, 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:
72dc82a
Parents:
f32a013
Message:

First step in implementing internal scheduling

File:
1 edited

Legend:

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

    rf32a013 r690f13c  
    1818
    1919#include "kernel_private.h"
     20
     21void set_owner( monitor_desc * this, thread_desc * owner ) {
     22        //Pass the monitor appropriately
     23        this->owner = owner;
     24
     25        //We are passing the monitor to someone else, which means recursion level is not 0
     26        this->recursion = owner ? 1 : 0;
     27}
    2028
    2129extern "C" {
     
    4654        }
    4755
     56        // leave pseudo code :
     57        //      decrement level
     58        //      leve == 0 ?
     59        //              no : done
     60        //              yes :
     61        //                      signal stack empty ?
     62        //                              has leader :
     63        //                                      bulk acquiring means we don't own the signal stack
     64        //                                      ignore it but don't release the monitor
     65        //                              yes :
     66        //                                      next in entry queue is new owner
     67        //                              no :
     68        //                                      top of the signal stack is the owner
     69        //                                      context switch to him right away
     70        //
    4871        void __leave_monitor_desc(monitor_desc * this) {
    4972                lock( &this->lock );
     
    5578                this->recursion -= 1;
    5679
    57                 //If we left the last level of recursion it means we are changing who owns the monitor
     80                //If we haven't left the last level of recursion
     81                //it means we don't need to do anything
     82                if( this->recursion != 0) {
     83                        unlock( &this->lock );
     84                        return;
     85                }
     86                       
     87                //If we don't own the signal stack then just leave it to the owner
     88                if( this->stack_owner ) {
     89                        assert( this->owner == this->stack_owner );
     90                        unlock( &this->lock );
     91                        return;
     92                }
     93
     94                //We are the stack owner and have left the last recursion level.
     95                //We are in charge of passing the monitor
    5896                thread_desc * new_owner = 0;
    59                 if( this->recursion == 0) {
    60                         //Get the next thread in the list
    61                         new_owner = this->owner = pop_head( &this->entry_queue );
    6297
    63                         //We are passing the monitor to someone else, which means recursion level is not 0
    64                         this->recursion = new_owner ? 1 : 0;
    65                 }       
     98                //Check the signaller stack
     99                new_owner = pop( &this->signal_stack );
     100                if( new_owner ) {
     101                        //The signaller stack is not empty,
     102                        //transfer control immediately
     103                        set_owner( this, new_owner );
     104                        ScheduleInternal( &this->lock, new_owner );
     105                        return;
     106                }
     107               
     108                // No signaller thread
     109                // Get the next thread in the entry_queue
     110                new_owner = pop_head( &this->entry_queue );
     111                set_owner( this, new_owner );
    66112
     113                //We can now let other threads in safely
    67114                unlock( &this->lock );
    68115
    69                 //If we have a new owner, we need to wake-up the thread
    70                 if( new_owner ) {
    71                         ScheduleThread( new_owner );
    72                 }
     116                //We need to wake-up the thread
     117                ScheduleThread( new_owner );
    73118        }
    74119}
Note: See TracChangeset for help on using the changeset viewer.