Changeset ab8c6a6
- Timestamp:
- Oct 26, 2020, 12:17:28 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 342be43
- Parents:
- 912cc7d7
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/exception.cfa
r912cc7d7 rab8c6a6 19 19 #include <unwind.h> 20 20 #undef HIDE_EXPORTS 21 22 extern void __cfactx_thrd_leave(); 21 23 } 22 24 … … 52 54 53 55 STOP_AT_END_FUNCTION(thread_cancelstop, 54 // TODO: Instead pass information to the joiner. 55 abort();56 __cfactx_thrd_leave(); 57 __cabi_abort( "Resumed cancelled thread" ); 56 58 ) 57 59 … … 85 87 stop_param = (void *)0x22; 86 88 } else { 89 this_thread->self_cor.cancellation = unwind_exception; 90 87 91 stop_func = thread_cancelstop; 88 92 stop_param = this_thread; -
libcfa/src/concurrency/monitor.cfa
r912cc7d7 rab8c6a6 306 306 /* paranoid */ verify( thrd->state == Halted ); 307 307 unpark( new_owner ); 308 }309 310 // Join a thread311 forall( dtype T | is_thread(T) )312 T & join( T & this ) {313 $monitor * m = get_monitor(this);314 void (*dtor)(T& mutex this) = ^?{};315 monitor_dtor_guard_t __guard = { &m, (fptr_t)dtor, true };316 {317 return this;318 }319 308 } 320 309 -
libcfa/src/concurrency/thread.cfa
r912cc7d7 rab8c6a6 19 19 20 20 #include "kernel_private.hfa" 21 #include "exception.hfa" 21 22 22 23 #define __CFA_INVOKE_PRIVATE__ … … 58 59 } 59 60 61 FORALL_DATA_INSTANCE(ThreadCancelled, (dtype thread_t), (thread_t)) 62 63 forall(dtype T) 64 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) { 65 dst->virtual_table = src->virtual_table; 66 dst->the_thread = src->the_thread; 67 dst->the_exception = src->the_exception; 68 } 69 70 forall(dtype T) 71 const char * msg(ThreadCancelled(T) *) { 72 return "ThreadCancelled"; 73 } 74 75 struct __cfaehm_node { 76 struct _Unwind_Exception unwind_exception; 77 struct __cfaehm_node * next; 78 int handler_index; 79 }; 80 81 forall(dtype T) 82 static void default_thread_cancel_handler(ThreadCancelled(T) & ) { 83 abort( "Unhandled thread cancellation.\n" ); 84 } 85 86 forall(dtype T | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))) 87 void ?{}( thread_dtor_guard_t & this, 88 T & thrd, void(*defaultResumptionHandler)(ThreadCancelled(T) &)) { 89 $monitor * m = get_monitor(thrd); 90 void (*dtor)(T& mutex this) = ^?{}; 91 bool join = defaultResumptionHandler != (void(*)(ThreadCancelled(T)&))0; 92 (this.mg){&m, (void(*)())dtor, join}; 93 { 94 $thread * desc = get_thread(thrd); 95 struct _Unwind_Exception * cancellation = desc->self_cor.cancellation; 96 if ( likely(0p == cancellation) ) { 97 return; 98 } else if ( Cancelled == desc->state ) { 99 return; 100 } 101 desc->state = Cancelled; 102 if (!join) { 103 defaultResumptionHandler = default_thread_cancel_handler; 104 } 105 ThreadCancelled(T) except; 106 // TODO: Remove explitate vtable set once trac#186 is fixed. 107 except.virtual_table = &get_exception_vtable(&except); 108 except.the_thread = &thrd; 109 except.the_exception = (exception_t *)(1 + (__cfaehm_node *)cancellation); 110 throwResume except; 111 112 except.the_exception->virtual_table->free( except.the_exception ); 113 free( cancellation ); 114 desc->self_cor.cancellation = 0p; 115 } 116 } 117 118 void ^?{}( thread_dtor_guard_t & this ) { 119 ^(this.mg){}; 120 } 121 60 122 //----------------------------------------------------------------------------- 61 123 // Starting and stopping threads … … 93 155 } 94 156 157 //----------------------------------------------------------------------------- 158 forall(dtype T | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))) 159 T & join( T & this ) { 160 thread_dtor_guard_t guard = { this, defaultResumptionHandler }; 161 return this; 162 } 163 95 164 // Local Variables: // 96 165 // mode: c // -
libcfa/src/concurrency/thread.hfa
r912cc7d7 rab8c6a6 22 22 #include "kernel.hfa" 23 23 #include "monitor.hfa" 24 #include "exception.hfa" 24 25 25 26 //----------------------------------------------------------------------------- 26 27 // thread trait 27 28 trait is_thread(dtype T) { 28 29 30 29 void ^?{}(T& mutex this); 30 void main(T& this); 31 $thread* get_thread(T& this); 31 32 }; 33 34 FORALL_DATA_EXCEPTION(ThreadCancelled, (dtype thread_t), (thread_t)) ( 35 thread_t * the_thread; 36 exception_t * the_exception; 37 ); 38 39 forall(dtype T) 40 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src); 41 42 forall(dtype T) 43 const char * msg(ThreadCancelled(T) *); 32 44 33 45 // define that satisfies the trait without using the thread keyword … … 65 77 static inline void ?{}($thread & this, const char * const name, struct cluster & cl ) { this{ name, cl, 0p, 65000 }; } 66 78 static inline void ?{}($thread & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, 0p, stackSize }; } 79 80 struct thread_dtor_guard_t { 81 monitor_dtor_guard_t mg; 82 }; 83 84 forall( dtype T | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) ) 85 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) ); 86 void ^?{}( thread_dtor_guard_t & this ); 67 87 68 88 //----------------------------------------------------------------------------- … … 108 128 //---------- 109 129 // join 110 forall( dtype T | is_thread(T) )130 forall( dtype T | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) ) 111 131 T & join( T & this ); 112 132 -
src/Concurrency/Keywords.cc
r912cc7d7 rab8c6a6 46 46 } 47 47 48 // Only detects threads constructed with the keyword thread. 49 inline static bool isThread( DeclarationWithType * decl ) { 50 Type * baseType = decl->get_type()->stripDeclarator(); 51 StructInstType * instType = dynamic_cast<StructInstType *>( baseType ); 52 if ( nullptr == instType ) { return false; } 53 return instType->baseStruct->is_thread(); 54 } 55 48 56 //============================================================================================= 49 57 // Pass declarations … … 119 127 "get_thread", 120 128 "thread keyword requires threads to be in scope, add #include <thread.hfa>\n", 121 " ",129 "ThreadCancelled", 122 130 true, 123 131 AggregateDecl::Thread … … 290 298 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first ); 291 299 void validate( DeclarationWithType * ); 292 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 293 void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 300 void addDtorStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 301 void addStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 302 void addThreadDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ); 294 303 295 304 static void implement( std::list< Declaration * > & translationUnit ) { … … 302 311 StructDecl* guard_decl = nullptr; 303 312 StructDecl* dtor_guard_decl = nullptr; 313 StructDecl* thread_guard_decl = nullptr; 304 314 305 315 static std::unique_ptr< Type > generic_func; … … 801 811 bool first = false; 802 812 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first ); 803 bool isDtor = CodeGen::isDestructor( decl->name );813 bool const isDtor = CodeGen::isDestructor( decl->name ); 804 814 805 815 // Is this function relevant to monitors … … 849 859 850 860 // Instrument the body 851 if( isDtor ) { 852 addDtorStatments( decl, body, mutexArgs ); 861 if ( isDtor && isThread( mutexArgs.front() ) ) { 862 if( !thread_guard_decl ) { 863 SemanticError( decl, "thread destructor requires threads to be in scope, add #include <thread.hfa>\n" ); 864 } 865 addThreadDtorStatements( decl, body, mutexArgs ); 866 } 867 else if ( isDtor ) { 868 addDtorStatements( decl, body, mutexArgs ); 853 869 } 854 870 else { 855 addStat ments( decl, body, mutexArgs );871 addStatements( decl, body, mutexArgs ); 856 872 } 857 873 } … … 870 886 assert( !dtor_guard_decl ); 871 887 dtor_guard_decl = decl; 888 } 889 else if( decl->name == "thread_dtor_guard_t" && decl->body ) { 890 assert( !thread_guard_decl ); 891 thread_guard_decl = decl; 872 892 } 873 893 } … … 908 928 } 909 929 910 void MutexKeyword::addDtorStat ments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {930 void MutexKeyword::addDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 911 931 Type * arg_type = args.front()->get_type()->clone(); 912 932 arg_type->set_mutex( false ); … … 957 977 958 978 //$monitor * __monitors[] = { get_monitor(a), get_monitor(b) }; 959 body->push_front( new DeclStmt( monitors) ); 960 } 961 962 void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 979 body->push_front( new DeclStmt( monitors ) ); 980 } 981 982 void MutexKeyword::addThreadDtorStatements( 983 FunctionDecl*, CompoundStmt * body, 984 const std::list<DeclarationWithType * > & args ) { 985 assert( args.size() == 1 ); 986 DeclarationWithType * arg = args.front(); 987 Type * arg_type = arg->get_type()->clone(); 988 assert( arg_type->get_mutex() ); 989 arg_type->set_mutex( false ); 990 991 // thread_dtor_guard_t __guard = { this, intptr( 0 ) }; 992 body->push_front( 993 new DeclStmt( new ObjectDecl( 994 "__guard", 995 noStorageClasses, 996 LinkageSpec::Cforall, 997 nullptr, 998 new StructInstType( 999 noQualifiers, 1000 thread_guard_decl 1001 ), 1002 new ListInit( 1003 { 1004 new SingleInit( new CastExpr( new VariableExpr( arg ), arg_type ) ), 1005 new SingleInit( new UntypedExpr( 1006 new NameExpr( "intptr" ), { 1007 new ConstantExpr( Constant::from_int( 0 ) ), 1008 } 1009 ) ), 1010 }, 1011 noDesignators, 1012 true 1013 ) 1014 )) 1015 ); 1016 } 1017 1018 void MutexKeyword::addStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 963 1019 ObjectDecl * monitors = new ObjectDecl( 964 1020 "__monitors", -
src/GenPoly/Specialize.cc
r912cc7d7 rab8c6a6 321 321 } 322 322 323 // Fold it into Specialize if we find a good way. 324 struct StaticThunks final : public WithShortCircuiting { 325 void previsit( Declaration * ) { 326 visit_children = false; 327 } 328 void postvisit( FunctionDecl * decl ) { 329 if ( isPrefix( decl->name, "_thunk" ) ) { 330 decl->storageClasses.is_static = true; 331 } 332 } 333 }; 334 323 335 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 324 336 PassVisitor<Specialize> spec; 325 337 mutateAll( translationUnit, spec ); 338 PassVisitor<StaticThunks> staticThunks; 339 acceptAll( translationUnit, staticThunks ); 326 340 } 327 341 } // namespace GenPoly
Note: See TracChangeset
for help on using the changeset viewer.