Changeset cc7f4b1
- Timestamp:
- Feb 28, 2017, 12:40:47 PM (8 years ago)
- 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:
- 2781e65, fd061ed3
- Parents:
- 4868be4
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.h
r4868be4 rcc7f4b1 60 60 61 61 struct coStack_t { 62 unsigned int size; // size of stack63 void *storage; // pointer to stack64 void *limit; // stack grows towards stack limit65 void *base; // base of stack66 void *context; // address of cfa_context_t67 void *top; // address of top of storage62 unsigned int size; // size of stack 63 void *storage; // pointer to stack 64 void *limit; // stack grows towards stack limit 65 void *base; // base of stack 66 void *context; // address of cfa_context_t 67 void *top; // address of top of storage 68 68 bool userStack; 69 69 }; … … 73 73 struct coroutine { 74 74 struct coStack_t stack; 75 const char *name; // textual name for coroutine/task, initialized by uC++ generated code76 int errno_; // copy of global UNIX variable errno77 enum coroutine_state state; // current execution status for coroutine78 struct coroutine *starter; // first coroutine to resume this one79 struct coroutine *last; // last coroutine to resume this one75 const char *name; // textual name for coroutine/task, initialized by uC++ generated code 76 int errno_; // copy of global UNIX variable errno 77 enum coroutine_state state; // current execution status for coroutine 78 struct coroutine *starter; // first coroutine to resume this one 79 struct coroutine *last; // last coroutine to resume this one 80 80 }; 81 81 82 82 struct thread { 83 struct coroutine c; // coroutine body used to store context84 struct signal_once terminated; // indicate if execuation state is not halted85 struct thread * next; // instrusive link field for threads83 struct coroutine c; // coroutine body used to store context 84 struct signal_once terminated; // indicate if execuation state is not halted 85 struct thread * next; // instrusive link field for threads 86 86 }; 87 87 -
src/libcfa/concurrency/monitor
r4868be4 rcc7f4b1 21 21 #include "invoke.h" 22 22 23 struct monitor{23 struct __monitor_t { 24 24 spinlock lock; 25 thread * holder;25 thread * owner; 26 26 simple_thread_list entry_queue; 27 unsigned int recursion; 27 28 }; 28 29 29 void enter(monitor *); 30 void leave(monitor *); 30 static inline void ?{}(__monitor_t * this) { 31 this->owner = 0; 32 this->recursion = 0; 33 } 31 34 32 struct monitor_guard { 33 monitor * m; 35 void enter(__monitor_t *); 36 void leave(__monitor_t *); 37 38 struct monitor_guard_t { 39 __monitor_t * m; 34 40 }; 35 41 36 static inline void ?{}( monitor_guard * this, monitor* m ) {42 static inline void ?{}( monitor_guard_t * this, __monitor_t * m ) { 37 43 this->m = m; 38 44 enter( this->m ); 39 45 } 40 46 41 static inline void ^?{}( monitor_guard * this ) {47 static inline void ^?{}( monitor_guard_t * this ) { 42 48 leave( this->m ); 43 49 } -
src/libcfa/concurrency/monitor.c
r4868be4 rcc7f4b1 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // monitor.c --8 // __monitor_t.c -- 9 9 // 10 10 // Author : Thierry Delisle … … 19 19 #include "kernel_private.h" 20 20 21 void enter( monitor* this) {21 void enter(__monitor_t * this) { 22 22 lock( &this->lock ); 23 23 thread * thrd = this_thread(); 24 24 25 if( this->holder ) { 25 if( !this->owner ) { 26 //No one has the monitor, just take it 27 this->owner = thrd; 28 this->recursion = 1; 29 } 30 else if( this->owner == thrd) { 31 //We already have the monitor, just not how many times we took it 32 assert( this->recursion > 0 ); 33 this->recursion += 1; 34 } 35 else { 36 //Some one else has the monitor, wait in line for it 26 37 append( &this->entry_queue, thrd ); 27 38 ScheduleInternal( &this->lock ); 28 return; 29 } 30 else { 31 this->holder = thrd; 39 40 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 41 return; 32 42 } 33 43 … … 35 45 } 36 46 37 void leave( monitor* this) {47 void leave(__monitor_t * this) { 38 48 lock( &this->lock ); 39 49 40 50 thread * thrd = this_thread(); 41 assert( thrd == this-> holder );51 assert( thrd == this->owner ); 42 52 43 this->holder = pop_head( &this->entry_queue ); 53 //Leaving a recursion level, decrement the counter 54 this->recursion -= 1; 55 56 //If we left the last level of recursion it means we are changing who owns the monitor 57 thread * new_owner = 0; 58 if( this->recursion == 0) { 59 //Get the next thread in the list 60 new_owner = this->owner = pop_head( &this->entry_queue ); 61 62 //We are passing the monitor to someone else, which means recursion level is not 0 63 this->recursion = new_owner ? 1 : 0; 64 } 44 65 45 66 unlock( &this->lock ); 46 67 47 if( this->holder ) ScheduleThread( this->holder ); 68 //If we have a new owner, we need to wake-up the thread 69 if( new_owner ) { 70 ScheduleThread( new_owner ); 71 } 48 72 } -
src/tests/monitor.c
r4868be4 rcc7f4b1 6 6 struct global_t { 7 7 int value; 8 monitorm;8 __monitor_t m; 9 9 }; 10 10 … … 16 16 17 17 void increment( /*mutex*/ global_t * this ) { 18 monitor_guard g = { &this->m }; 19 this->value += 1; 18 monitor_guard_t g1 = { &this->m }; 19 { 20 monitor_guard_t g2 = { &this->m }; 21 { 22 monitor_guard_t g3 = { &this->m }; 23 this->value += 1; 24 } 25 } 20 26 } 21 27
Note: See TracChangeset
for help on using the changeset viewer.