Changes in / [168c007:94a8123]
- Files:
-
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/concurrency/thePlan.md
r168c007 r94a8123 8 8 _Phase 2_ : Minimum Viable Product 9 9 done - Monitor type and enter/leave mutex member routines 10 done - Multi monitors calls, 11 done - Monitors as a language feature (not calling enter/leave by hand) 10 Monitors as a language feature (not calling enter/leave by hand) 12 11 Internal scheduling 13 12 14 13 _Phase 3_ : Kernel features 15 Preemption16 14 Detach thread 17 15 Cluster migration 16 Preemption 18 17 19 18 _Phase 4_ : Monitor features 19 Multi monitors calls, 20 20 External scheduling 21 21 -
src/Concurrency/Keywords.cc
r168c007 r94a8123 17 17 #include "Concurrency/Keywords.h" 18 18 19 #include "SymTab/AddVisit.h"20 19 #include "SynTree/Declaration.h" 21 20 #include "SynTree/Expression.h" … … 30 29 namespace { 31 30 const std::list<Label> noLabels; 32 const std::list< Attribute * > noAttributes;33 31 Type::StorageClasses noStorage; 34 32 Type::Qualifiers noQualifiers; … … 65 63 // void main( MyCoroutine * this ); 66 64 // 67 class CoroutineKeyword final : public Visitor { 68 template< typename Visitor > 69 friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 70 public: 71 72 using Visitor::visit; 73 virtual void visit( StructDecl * decl ) override final; 74 75 void handle( StructDecl * ); 76 Declaration * addField( StructDecl * ); 77 void addRoutines( StructDecl *, Declaration * ); 78 79 static void implement( std::list< Declaration * > & translationUnit ) { 80 CoroutineKeyword impl; 81 SymTab::acceptAndAdd( translationUnit, impl ); 82 } 83 84 private: 85 std::list< Declaration * > declsToAdd, declsToAddAfter; 86 StructDecl* coroutine_decl = nullptr; 65 class CoroutineKeyword final : public Mutator { 66 public: 67 68 static void implement( std::list< Declaration * > & translationUnit ) {} 87 69 }; 88 70 … … 115 97 116 98 using Visitor::visit; 117 virtual void visit( FunctionDecl * decl ) override final;118 virtual void visit( StructDecl * decl ) override final;99 virtual void visit( FunctionDecl *functionDecl ) override final; 100 virtual void visit( StructDecl *functionDecl ) override final; 119 101 120 102 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* ); … … 129 111 private: 130 112 StructDecl* monitor_decl = nullptr; 131 StructDecl* guard_decl = nullptr;132 113 }; 133 114 … … 143 124 144 125 //============================================================================================= 145 // Coroutine keyword implementation146 //=============================================================================================147 void CoroutineKeyword::visit(StructDecl * decl) {148 if( decl->get_name() == "coroutine_desc" ) {149 assert( !coroutine_decl );150 coroutine_decl = decl;151 }152 else if ( decl->is_coroutine() ) {153 handle( decl );154 }155 156 }157 158 void CoroutineKeyword::handle( StructDecl * decl ) {159 if( ! decl->has_body() ) return;160 161 if( !coroutine_decl ) throw SemanticError( "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", decl );162 163 Declaration * field = addField( decl );164 addRoutines( decl, field );165 }166 167 Declaration * CoroutineKeyword::addField( StructDecl * decl ) {168 Declaration * cor = new ObjectDecl(169 "__cor",170 noStorage,171 LinkageSpec::Cforall,172 nullptr,173 new StructInstType(174 noQualifiers,175 coroutine_decl176 ),177 nullptr178 );179 180 decl->get_members().push_back( cor );181 182 return cor;183 }184 185 void CoroutineKeyword::addRoutines( StructDecl * decl, Declaration * field ) {186 FunctionType * type = new FunctionType( noQualifiers, false );187 type->get_parameters().push_back(188 new ObjectDecl(189 "this",190 noStorage,191 LinkageSpec::Cforall,192 nullptr,193 new PointerType(194 noQualifiers,195 new StructInstType(196 noQualifiers,197 decl198 )199 ),200 nullptr201 )202 );203 type->get_returnVals().push_back(204 new ObjectDecl(205 "ret",206 noStorage,207 LinkageSpec::Cforall,208 nullptr,209 new PointerType(210 noQualifiers,211 new StructInstType(212 noQualifiers,213 coroutine_decl214 )215 ),216 nullptr217 )218 );219 220 CompoundStmt * statement = new CompoundStmt( noLabels );221 statement->push_back(222 new ReturnStmt(223 noLabels,224 new AddressExpr(225 new UntypedMemberExpr(226 new NameExpr( "__cor" ),227 new UntypedExpr(228 new NameExpr( "*?" ),229 { new NameExpr( "this" ) }230 )231 )232 )233 )234 );235 236 FunctionDecl * get_decl = new FunctionDecl(237 "get_coroutine",238 Type::Static,239 LinkageSpec::Cforall,240 type,241 statement,242 noAttributes,243 Type::Inline244 );245 246 declsToAddAfter.push_back( get_decl );247 248 get_decl->fixUniqueId();249 }250 251 252 //=============================================================================================253 126 // Mutex keyword implementation 254 127 //============================================================================================= … … 264 137 if( ! body ) return; 265 138 266 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 267 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 268 139 assert(monitor_decl); 269 140 addStatments( body, mutexArgs ); 270 141 } … … 275 146 monitor_decl = decl; 276 147 } 277 else if( decl->get_name() == "monitor_guard_t" ) {278 assert( !guard_decl );279 guard_decl = decl;280 }281 148 } 282 149 … … 308 175 309 176 //Make sure that typed isn't mutex 310 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );177 if( ! base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg ); 311 178 } 312 179 313 180 void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 181 314 182 ObjectDecl * monitors = new ObjectDecl( 315 183 "__monitors", … … 350 218 new StructInstType( 351 219 noQualifiers, 352 guard_decl220 "monitor_guard_t" 353 221 ), 354 222 new ListInit( … … 356 224 new SingleInit( new VariableExpr( monitors ) ), 357 225 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ) 358 }, 359 noDesignators, 360 true 226 } 361 227 ) 362 228 )) 363 229 ); 364 230 365 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b)};231 //monitor_desc * __monitors[] = { a, b }; 366 232 body->push_front( new DeclStmt( noLabels, monitors) ); 367 233 } -
src/Parser/DeclarationNode.cc
r168c007 r94a8123 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 17 15:46:33201713 // Update Count : 101 812 // Last Modified On : Fri Mar 17 08:46:05 2017 13 // Update Count : 1017 14 14 // 15 15 … … 36 36 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; 37 37 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" }; 38 const char * DeclarationNode::aggregateNames[] = { "struct", "union", " trait", "coroutine", "monitor", "thread", "NoAggregateNames" };38 const char * DeclarationNode::aggregateNames[] = { "struct", "union", "context", "NoAggregateNames" }; 39 39 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" }; 40 40 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "NoBuiltinTypeNames" }; -
src/Parser/ParseNode.h
r168c007 r94a8123 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 17 15:42:18201713 // Update Count : 77 712 // Last Modified On : Thu Mar 16 08:32:43 2017 13 // Update Count : 776 14 14 // 15 15 … … 206 206 enum Signedness { Signed, Unsigned, NoSignedness }; 207 207 enum Length { Short, Long, LongLong, NoLength }; 208 enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread,NoAggregate };208 enum Aggregate { Struct, Union, Trait, NoAggregate }; 209 209 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass }; 210 210 enum BuiltinType { Valist, Zero, One, NoBuiltinType }; -
src/Parser/TypeData.cc
r168c007 r94a8123 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 17 15:52:43201713 // Update Count : 56 312 // Last Modified On : Fri Mar 17 08:46:10 2017 13 // Update Count : 560 14 14 // 15 15 … … 619 619 switch ( td->aggregate.kind ) { 620 620 case DeclarationNode::Struct: 621 case DeclarationNode::Coroutine: 622 case DeclarationNode::Monitor: 623 case DeclarationNode::Thread: 624 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes ); 621 at = new StructDecl( *td->aggregate.name, attributes ); 625 622 buildForall( td->aggregate.params, at->get_parameters() ); 626 623 break; … … 659 656 switch ( type->aggregate.kind ) { 660 657 case DeclarationNode::Struct: 661 case DeclarationNode::Coroutine:662 case DeclarationNode::Monitor:663 case DeclarationNode::Thread:664 658 ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl ); 665 659 break; … … 677 671 switch ( type->aggregate.kind ) { 678 672 case DeclarationNode::Struct: 679 case DeclarationNode::Coroutine:680 case DeclarationNode::Monitor:681 case DeclarationNode::Thread:682 673 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 683 674 break; … … 712 703 switch ( type->aggregate.kind ) { 713 704 case DeclarationNode::Struct: 714 case DeclarationNode::Coroutine:715 case DeclarationNode::Monitor:716 case DeclarationNode::Thread:717 705 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 718 706 break; -
src/Parser/lex.ll
r168c007 r94a8123 202 202 __const__ { KEYWORD_RETURN(CONST); } // GCC 203 203 continue { KEYWORD_RETURN(CONTINUE); } 204 coroutine { KEYWORD_RETURN(COROUTINE); } // CFA204 _Coroutine { KEYWORD_RETURN(COROUTINE); } // CFA 205 205 default { KEYWORD_RETURN(DEFAULT); } 206 206 disable { KEYWORD_RETURN(DISABLE); } // CFA -
src/Parser/parser.yy
r168c007 r94a8123 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 17 15:42:22201713 // Update Count : 231 712 // Last Modified On : Thu Mar 16 12:57:03 2017 13 // Update Count : 2316 14 14 // 15 15 … … 1638 1638 { $$ = DeclarationNode::Union; } 1639 1639 | COROUTINE 1640 { $$ = DeclarationNode:: Coroutine; }1640 { $$ = DeclarationNode::Struct; } 1641 1641 | MONITOR 1642 { $$ = DeclarationNode:: Monitor; }1642 { $$ = DeclarationNode::Struct; } 1643 1643 | THREAD 1644 { $$ = DeclarationNode:: Thread; }1644 { $$ = DeclarationNode::Struct; } 1645 1645 ; 1646 1646 -
src/SynTree/Declaration.h
r168c007 r94a8123 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 17 16:05:08201713 // Update Count : 1 2112 // Last Modified On : Thu Mar 16 08:34:11 2017 13 // Update Count : 118 14 14 // 15 15 … … 255 255 typedef AggregateDecl Parent; 256 256 public: 257 StructDecl( const std::string &name, DeclarationNode::Aggregate kind = DeclarationNode::Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >() ) : Parent( name, attributes ), kind( kind) {}257 StructDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >() ) : Parent( name, attributes ) {} 258 258 StructDecl( const StructDecl &other ) : Parent( other ) {} 259 259 260 bool is_coroutine() { return kind == DeclarationNode::Coroutine; }261 bool is_monitor() { return kind == DeclarationNode::Monitor; }262 bool is_thread() { return kind == DeclarationNode::Thread; }263 264 260 virtual StructDecl *clone() const { return new StructDecl( *this ); } 265 261 virtual void accept( Visitor &v ) { v.visit( this ); } 266 262 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 267 263 private: 268 DeclarationNode::Aggregate kind;269 264 virtual std::string typeString() const; 270 265 }; -
src/SynTree/Type.h
r168c007 r94a8123 117 117 bool operator!=( Qualifiers other ) const { return (val & Mask) != (other.val & Mask); } 118 118 bool operator<=( Qualifiers other ) const { 119 return is_const <= other.is_const //Any non-const converts to const without cost 120 && is_volatile <= other.is_volatile //Any non-volatile converts to volatile without cost 121 && is_mutex >= other.is_mutex //Any mutex converts to non-mutex without cost 122 && is_atomic == other.is_atomic; //No conversion from atomic to non atomic is free 119 return is_const <= other.is_const && is_volatile <= other.is_volatile && 120 is_mutex >= other.is_mutex && is_atomic == other.is_atomic; 123 121 } 124 122 bool operator<( Qualifiers other ) const { return *this != other && *this <= other; } -
src/benchmark/CorCtxSwitch.c
r168c007 r94a8123 24 24 25 25 struct GreatSuspender { 26 coroutine_desc __cor;26 coroutine_desc c; 27 27 }; 28 28 -
src/benchmark/bench.c
r168c007 r94a8123 86 86 //======================================= 87 87 88 struct CoroutineDummy { coroutine_desc __cor; };88 struct CoroutineDummy { coroutine_desc c; }; 89 89 DECL_COROUTINE(CoroutineDummy); 90 90 void main(CoroutineDummy * this) {} … … 119 119 struct CoroutineResume { 120 120 int N; 121 coroutine_desc __cor;121 coroutine_desc c; 122 122 }; 123 123 … … 150 150 //======================================= 151 151 152 struct ThreadDummy { thread_desc __thrd; };152 struct ThreadDummy { thread_desc t; }; 153 153 DECL_THREAD(ThreadDummy); 154 154 void main(ThreadDummy * this) {} … … 180 180 int N; 181 181 long long result; 182 thread_desc __thrd;182 thread_desc t; 183 183 }; 184 184 -
src/benchmark/csv-data.c
r168c007 r94a8123 26 26 27 27 struct GreatSuspender { 28 coroutine_desc __cor;28 coroutine_desc c; 29 29 }; 30 30 -
src/driver/Makefile.am
r168c007 r94a8123 32 32 33 33 install-exec-hook: 34 @test -z "$(CFA_BINDIR)" || $(MKDIR_P) "$(CFA_BINDIR)"35 34 @echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa '$(CFA_BINDIR)/$(CFA_NAME)'"; \ 36 35 $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa $(CFA_BINDIR)/$(CFA_NAME) || exit $$? -
src/driver/Makefile.in
r168c007 r94a8123 530 530 531 531 install-exec-hook: 532 @test -z "$(CFA_BINDIR)" || $(MKDIR_P) "$(CFA_BINDIR)"533 532 @echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa '$(CFA_BINDIR)/$(CFA_NAME)'"; \ 534 533 $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa $(CFA_BINDIR)/$(CFA_NAME) || exit $$? -
src/examples/multicore.c
r168c007 r94a8123 2 2 #include <thread> 3 3 4 struct MyThread { thread_desc __thrd; };4 struct MyThread { thread_desc t; }; 5 5 6 6 DECL_THREAD(MyThread); -
src/libcfa/concurrency/coroutine
r168c007 r94a8123 30 30 }; 31 31 32 #define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X* this) { return &this-> __cor; } void main(X* this)32 #define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X* this) { return &this->c; } void main(X* this) 33 33 34 34 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/invoke.c
r168c007 r94a8123 56 56 57 57 void CtxInvokeThread( 58 void (*dtor)(void *),59 58 void (*main)(void *), 60 59 struct thread_desc *(*get_thread)(void *), … … 64 63 65 64 struct thread_desc* thrd = get_thread( this ); 66 struct coroutine_desc* cor = &thrd->c or;65 struct coroutine_desc* cor = &thrd->c; 67 66 cor->state = Active; 68 67 … … 92 91 struct FakeStack { 93 92 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 94 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls)95 uint16_t fcw;// X97 FPU control word (preserved across function calls)96 void *rturn; // where to go on return from uSwitch93 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 94 uint16_t fcw; // X97 FPU control word (preserved across function calls) 95 void *rturn; // where to go on return from uSwitch 97 96 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 98 97 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here … … 106 105 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 107 106 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 108 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520109 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7110 107 111 108 #elif defined( __x86_64__ ) 112 109 113 110 struct FakeStack { 114 void *fixedRegisters[5]; 115 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls)116 uint16_t fcw; // X97 FPU control word (preserved across function calls)117 void *rturn; // where to go on return from uSwitch118 void *dummyReturn; 111 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 112 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 113 uint16_t fcw; // X97 FPU control word (preserved across function calls) 114 void *rturn; // where to go on return from uSwitch 115 void *dummyReturn; // NULL return address to provide proper alignment 119 116 }; 120 117 -
src/libcfa/concurrency/invoke.h
r168c007 r94a8123 28 28 #define unlikely(x) __builtin_expect(!!(x), 0) 29 29 #define thread_local _Thread_local 30 #define SCHEDULER_CAPACITY 10 30 31 31 32 struct spinlock { … … 59 60 60 61 struct coStack_t { 61 unsigned int size; 62 void *storage; 63 void *limit; 64 void *base; 65 void *context; 66 void *top; 67 bool userStack; // whether or not the user allocated the stack62 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 bool userStack; 68 69 }; 69 70 … … 71 72 72 73 struct coroutine_desc { 73 struct coStack_t stack; // stack information of the coroutine74 const char *name; 75 int errno_; 76 enum coroutine_state state; 77 struct coroutine_desc *starter; // first coroutine to resume this one78 struct coroutine_desc *last; // last coroutine to resume this one74 struct coStack_t stack; 75 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_desc *starter; // first coroutine to resume this one 79 struct coroutine_desc *last; // last coroutine to resume this one 79 80 }; 80 81 81 82 struct thread_desc { 82 struct coroutine_desc c or;// coroutine body used to store context83 struct coroutine_desc c; // coroutine body used to store context 83 84 struct signal_once terminated; // indicate if execuation state is not halted 84 struct thread_desc * next; // instrusive link field for threads85 struct thread_desc * next; // instrusive link field for threads 85 86 }; 86 87 -
src/libcfa/concurrency/kernel.c
r168c007 r94a8123 107 107 108 108 void ?{}( thread_desc * this, current_stack_info_t * info) { 109 (&this->c or){ info };109 (&this->c){ info }; 110 110 } 111 111 … … 113 113 // Processor coroutine 114 114 void ?{}(processorCtx_t * this, processor * proc) { 115 (&this-> __cor){};115 (&this->c){}; 116 116 this->proc = proc; 117 117 proc->runner = this; … … 119 119 120 120 void ?{}(processorCtx_t * this, processor * proc, current_stack_info_t * info) { 121 (&this-> __cor){ info };121 (&this->c){ info }; 122 122 this->proc = proc; 123 123 proc->runner = this; … … 255 255 processorCtx_t proc_cor_storage = { proc, &info }; 256 256 257 LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage. __cor.stack.base);257 LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage.c.stack.base); 258 258 259 259 //Set global state 260 proc->current_coroutine = &proc->runner-> __cor;260 proc->current_coroutine = &proc->runner->c; 261 261 proc->current_thread = NULL; 262 262 … … 268 268 // back to here. Instead directly call the main since we already are on the 269 269 // appropriate stack. 270 proc_cor_storage. __cor.state = Active;270 proc_cor_storage.c.state = Active; 271 271 main( &proc_cor_storage ); 272 proc_cor_storage. __cor.state = Halted;272 proc_cor_storage.c.state = Halted; 273 273 274 274 // Main routine of the core returned, the core is now fully terminated … … 359 359 this_processor = systemProcessor; 360 360 this_processor->current_thread = mainThread; 361 this_processor->current_coroutine = &mainThread->c or;361 this_processor->current_coroutine = &mainThread->c; 362 362 363 363 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX -
src/libcfa/concurrency/kernel_private.h
r168c007 r94a8123 35 35 struct processorCtx_t { 36 36 processor * proc; 37 coroutine_desc __cor;37 coroutine_desc c; 38 38 }; 39 39 -
src/libcfa/concurrency/monitor
r168c007 r94a8123 34 34 } 35 35 36 //Basic entering routine 37 void enter(monitor_desc *); 38 void leave(monitor_desc *); 39 36 40 //Array entering routine 37 41 void enter(monitor_desc **, int count); … … 45 49 static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) { 46 50 return ((intptr_t)lhs) < ((intptr_t)rhs); 51 } 52 53 static inline void ?{}( monitor_guard_t * this, monitor_desc ** m ) { 54 this->m = m; 55 this->count = 1; 56 enter( *this->m ); 47 57 } 48 58 -
src/libcfa/concurrency/monitor.c
r168c007 r94a8123 74 74 void enter(monitor_desc ** monitors, int count) { 75 75 for(int i = 0; i < count; i++) { 76 // printf("%d\n", i); 76 77 enter( monitors[i] ); 77 78 } … … 80 81 void leave(monitor_desc ** monitors, int count) { 81 82 for(int i = count - 1; i >= 0; i--) { 83 // printf("%d\n", i); 82 84 leave( monitors[i] ); 83 85 } -
src/libcfa/concurrency/thread
r168c007 r94a8123 28 28 // Anything that is resumed is a coroutine. 29 29 trait is_thread(dtype T) { 30 void ^?{}(T* this);31 30 void main(T* this); 32 31 thread_desc* get_thread(T* this); 33 32 }; 34 33 35 #define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this-> __thrd; } void main(X* this)34 #define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this->t; } void main(X* this) 36 35 37 36 forall( dtype T | is_thread(T) ) 38 37 static inline coroutine_desc* get_coroutine(T* this) { 39 return &get_thread(this)->c or;38 return &get_thread(this)->c; 40 39 } 41 40 42 41 static inline coroutine_desc* get_coroutine(thread_desc* this) { 43 return &this->c or;42 return &this->c; 44 43 } 45 44 … … 65 64 void ?{}( scoped(T)* this, P params ); 66 65 67 forall( dtype T | sized(T) | is_thread(T) )66 forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } ) 68 67 void ^?{}( scoped(T)* this ); 69 68 -
src/libcfa/concurrency/thread.c
r168c007 r94a8123 42 42 43 43 void ?{}(thread_desc* this) { 44 (&this->c or){};45 this->c or.name = "Anonymous Coroutine";44 (&this->c){}; 45 this->c.name = "Anonymous Coroutine"; 46 46 (&this->terminated){}; 47 47 this->next = NULL; … … 49 49 50 50 void ^?{}(thread_desc* this) { 51 ^(&this->c or){};51 ^(&this->c){}; 52 52 } 53 53 … … 64 64 } 65 65 66 forall( dtype T | sized(T) | is_thread(T) )66 forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } ) 67 67 void ^?{}( scoped(T)* this ) { 68 68 stop(&this->handle); … … 120 120 extern "C" { 121 121 void __thread_signal_termination( thread_desc * this ) { 122 this->c or.state = Halted;122 this->c.state = Halted; 123 123 LIB_DEBUG_PRINTF("Thread end : %p\n", this); 124 124 signal( &this->terminated ); -
src/main.cc
r168c007 r94a8123 241 241 OPTPRINT( "fixNames" ) 242 242 CodeGen::fixNames( translationUnit ); 243 OPTPRINT( " genInit" )243 OPTPRINT( "tweakInit" ) 244 244 InitTweak::genInit( translationUnit ); 245 245 OPTPRINT( "expandMemberTuples" ); -
src/tests/coroutine.c
r168c007 r94a8123 2 2 #include <coroutine> 3 3 4 coroutineFibonacci {4 struct Fibonacci { 5 5 int fn; // used for communication 6 coroutine_desc c; 6 7 }; 7 8 … … 10 11 } 11 12 13 coroutine_desc* get_coroutine(Fibonacci* this) { 14 return &this->c; 15 } 16 12 17 void main(Fibonacci* this) { 18 #ifdef MORE_DEBUG 19 sout | "Starting main of coroutine " | this | endl; 20 sout | "Started from " | this->c.last | endl; 21 #endif 13 22 int fn1, fn2; // retained between resumes 14 23 this->fn = 0; … … 36 45 int main() { 37 46 Fibonacci f1, f2; 47 #ifdef MORE_DEBUG 48 Fibonacci *pf1 = &f1, *pf2 = &f2; 49 coroutine_desc *cf1 = &f1.c, *cf2 = &f2.c; 50 covptr_t *vf1 = vtable(pf1), *vf2 = vtable(pf2); 51 coroutine_desc *cv1 = get_coroutine(vf1), *cv2 = get_coroutine(vf2); 52 Fibonacci *ov1 = (Fibonacci *)get_object(vf1), *ov2 = (Fibonacci *)get_object(vf2); 53 54 sout | "User coroutines : " | pf1 | ' ' | pf2 | endl; 55 sout | "Coroutine data : " | cf1 | ' ' | cf2 | endl; 56 sout | "Vptr address : " | vf1 | ' ' | vf2 | endl; 57 sout | "Vptr obj data : " | ov1 | ' ' | ov2 | endl; 58 sout | "Vptr cor data : " | cv1 | ' ' | cv2 | endl; 59 #endif 38 60 for ( int i = 1; i <= 10; i += 1 ) { 39 61 sout | next(&f1) | ' ' | next(&f2) | endl; -
src/tests/monitor.c
r168c007 r94a8123 13 13 } 14 14 15 monitor_desc * get_monitor( global_t * this ) { 16 return &this->m; 15 static global_t global; 16 17 void increment( /*mutex*/ global_t * this ) { 18 monitor_desc * mon = &this->m; 19 monitor_guard_t g1 = { &mon }; 20 { 21 monitor_guard_t g2 = { &mon }; 22 { 23 monitor_guard_t g3 = { &mon }; 24 this->value += 1; 25 } 26 } 17 27 } 18 28 19 static global_t global; 20 21 void increment3( global_t * mutex this ) { 22 this->value += 1; 23 } 24 25 void increment2( global_t * mutex this ) { 26 increment3( this ); 27 } 28 29 void increment( global_t * mutex this ) { 30 increment2( this ); 31 } 32 33 struct MyThread { thread_desc __thrd; }; 29 struct MyThread { thread_desc t; }; 34 30 35 31 DECL_THREAD(MyThread); -
src/tests/multi-monitor.c
r168c007 r94a8123 6 6 static int global12, global23, global13; 7 7 8 struct monitor_t { 9 monitor_desc m; 10 }; 8 static monitor_desc m1, m2, m3; 11 9 12 monitor_desc * get_monitor( monitor_t * this ) { 13 return &this->m; 14 } 15 16 static monitor_t m1, m2, m3; 17 18 void increment( monitor_t * mutex p1, monitor_t * mutex p2, int * value ) { 10 void increment( /*mutex*/ monitor_desc * p1, /*mutex*/ monitor_desc * p2, int * value ) { 11 monitor_desc * mons[] = { p1, p2 }; 12 monitor_guard_t g = { mons, 2 }; 19 13 *value += 1; 20 14 } 21 15 22 16 struct MyThread { 23 thread_desc __thrd;17 thread_desc t; 24 18 int target; 25 19 }; -
src/tests/thread.c
r168c007 r94a8123 4 4 #include <thread> 5 5 6 struct First { thread_desc __thrd; signal_once* lock; };7 struct Second { thread_desc __thrd; signal_once* lock; };6 struct First { thread_desc t; signal_once* lock; }; 7 struct Second { thread_desc t; signal_once* lock; }; 8 8 9 9 DECL_THREAD(First);
Note: See TracChangeset
for help on using the changeset viewer.