Changes in / [72dc82a:936a287]


Ignore:
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/concurrency/thePlan.md

    r72dc82a r936a287  
    1010done - Multi monitors calls,
    1111done - Monitors as a language feature (not calling enter/leave by hand)
     12Internal scheduling
    1213
    13 _Phase 3_ : Monitor features
    14 Internal scheduling
    15 External scheduling
    16 
    17 _Phase 4_ : Kernel features
     14_Phase 3_ : Kernel features
    1815Preemption
    1916Detach thread
    2017Cluster migration
     18
     19_Phase 4_ : Monitor features
     20External scheduling
    2121
    2222_Phase 5_ : Performance
  • src/libcfa/concurrency/invoke.h

    r72dc82a r936a287  
    3838      };
    3939
    40       struct simple_thread_stack {
    41             struct thread_desc * top;
    42       };
    43 
    4440      #ifdef __CFORALL__
    4541      extern "Cforall" {
     
    4743            void append( struct simple_thread_list *, struct thread_desc * );
    4844            struct thread_desc * pop_head( struct simple_thread_list * );
    49 
    50             void ?{}( struct simple_thread_stack * );
    51             void push( struct simple_thread_stack *, struct thread_desc * );           
    52             struct thread_desc * pop( struct simple_thread_stack * );
    5345
    5446            void ?{}(spinlock * this);
     
    8274            struct thread_desc * owner;
    8375            struct simple_thread_list entry_queue;
    84             struct simple_thread_stack signal_stack;
    85             struct monitor_desc * stack_owner;
    8676            unsigned int recursion;
    8777      };
  • src/libcfa/concurrency/kernel.c

    r72dc82a r936a287  
    294294// Scheduler routines
    295295void ScheduleThread( thread_desc * thrd ) {
    296         if( !thrd ) return;
    297 
    298296        assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
    299297       
     
    470468        return head;
    471469}
    472 
    473 void ?{}( simple_thread_stack * this ) {
    474         this->top = NULL;
    475 }
    476 
    477 void push( simple_thread_stack * this, thread_desc * t ) {
    478         assert(t->next != NULL);
    479         t->next = this->top;
    480         this->top = t;
    481 }
    482 
    483 thread_desc * pop( simple_thread_stack * this ) {
    484         thread_desc * top = this->top;
    485         if( top ) {
    486                 this->top = top->next;
    487                 top->next = NULL;
    488         }       
    489         return top;
    490 }
    491470// Local Variables: //
    492471// mode: c //
  • src/libcfa/concurrency/monitor

    r72dc82a r936a287  
    1818#define MONITOR_H
    1919
    20 #include <stddef.h>
    21 
    2220#include "assert"
    2321#include "invoke.h"
     
    2523
    2624static inline void ?{}(monitor_desc * this) {
    27         this->owner = NULL;
    28       this->stack_owner = NULL;
     25        this->owner = 0;
    2926        this->recursion = 0;
    3027}
  • src/libcfa/concurrency/monitor.c

    r72dc82a r936a287  
    1818
    1919#include "kernel_private.h"
    20 
    21 void 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 }
    2820
    2921extern "C" {
     
    5446        }
    5547
    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         //
    7148        void __leave_monitor_desc(monitor_desc * this) {
    7249                lock( &this->lock );
     
    7855                this->recursion -= 1;
    7956
    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                 }
     57                //If we left the last level of recursion it means we are changing who owns the monitor
     58                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 );
    9362
    94                 //We are the stack owner and have left the last recursion level.
    95                 //We are in charge of passing the monitor
    96                 thread_desc * new_owner = 0;
     63                        //We are passing the monitor to someone else, which means recursion level is not 0
     64                        this->recursion = new_owner ? 1 : 0;
     65                }       
    9766
    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 );
    112 
    113                 //We can now let other threads in safely
    11467                unlock( &this->lock );
    11568
    116                 //We need to wake-up the thread
    117                 ScheduleThread( new_owner );
     69                //If we have a new owner, we need to wake-up the thread
     70                if( new_owner ) {
     71                        ScheduleThread( new_owner );
     72                }
    11873        }
    11974}
Note: See TracChangeset for help on using the changeset viewer.