Changeset a9ce782
- Timestamp:
- Feb 7, 2026, 1:40:26 PM (15 hours ago)
- Branches:
- stuck-waitfor-destruct
- Parents:
- c7d106a
- git-author:
- Matthew Au-Yeung <mw2auyeu@…> (02/07/26 13:40:05)
- git-committer:
- Matthew Au-Yeung <mw2auyeu@…> (02/07/26 13:40:26)
- Files:
-
- 1 added
- 10 edited
-
libcfa/src/bits/defs.hfa (modified) (1 diff)
-
libcfa/src/concurrency/invoke.h (modified) (4 diffs)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (1 diff)
-
libcfa/src/concurrency/monitor.cfa (modified) (7 diffs)
-
libcfa/src/concurrency/monitor.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/thread.cfa (modified) (4 diffs)
-
libcfa/src/concurrency/thread.hfa (modified) (1 diff)
-
src/Concurrency/Keywords.cpp (modified) (7 diffs)
-
src/Concurrency/MutexFuncHash.hpp (added)
-
src/Concurrency/Waitfor.cpp (modified) (2 diffs)
-
src/Validate/Autogen.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/defs.hfa
rc7d106a ra9ce782 26 26 27 27 typedef void (* fptr_t)(); 28 typedef uint64_t func_id_t; 28 29 typedef int_fast16_t __lock_size_t; 29 30 -
libcfa/src/concurrency/invoke.h
rc7d106a ra9ce782 159 159 // last function that acquired monitors 160 160 fptr_t func; 161 162 // hash-based function identity for cross-TU matching 163 func_id_t func_id; 161 164 }; 162 165 … … 288 291 (this.size){0}; 289 292 (this.func){NULL}; 290 } 291 292 static inline void ?{}(__monitor_group_t & this, struct monitor$ ** data, __lock_size_t size, fptr_t func) { 293 (this.func_id){0}; 294 } 295 296 static inline void ?{}(__monitor_group_t & this, struct monitor$ ** data, __lock_size_t size, fptr_t func, func_id_t func_id) { 293 297 (this.data){data}; 294 298 (this.size){size}; 295 299 (this.func){func}; 300 (this.func_id){func_id}; 296 301 } 297 302 … … 299 304 if( (lhs.data != 0) != (rhs.data != 0) ) return false; 300 305 if( lhs.size != rhs.size ) return false; 301 if( lhs.func != rhs.func ) return false; 306 // Use hash-based comparison when both sides have a valid func_id, 307 // otherwise fall back to function pointer comparison (for library code 308 // like join() that cannot compute the hash at compile time). 309 if( lhs.func_id != 0 && rhs.func_id != 0 ) { 310 if( lhs.func_id != rhs.func_id ) return false; 311 } else { 312 if( lhs.func != rhs.func ) return false; 313 } 302 314 303 315 // Check that all the monitors match … … 314 326 lhs.size = rhs.size; 315 327 lhs.func = rhs.func; 328 lhs.func_id = rhs.func_id; 316 329 } 317 330 } -
libcfa/src/concurrency/kernel/startup.cfa
rc7d106a ra9ce782 517 517 doregister(curr_cluster, this); 518 518 519 monitors{ &self_mon_p, 1, (fptr_t)0 };519 monitors{ &self_mon_p, 1, (fptr_t)0, (func_id_t)0 }; 520 520 } 521 521 -
libcfa/src/concurrency/monitor.cfa
rc7d106a ra9ce782 140 140 } 141 141 142 static void __dtor_enter( monitor$ * this, fptr_t func, bool join ) {142 static void __dtor_enter( monitor$ * this, fptr_t func, func_id_t func_id, bool join ) { 143 143 thread$ * thrd = active_thread(); 144 144 #if defined( __CFA_WITH_VERIFY__ ) … … 190 190 __lock_size_t count = 1; 191 191 monitor$ ** monitors = &this; 192 __monitor_group_t group = { &this, 1, func };192 __monitor_group_t group = { &this, 1, func, func_id }; 193 193 if ( is_accepted( this, group) ) { 194 194 __cfaabi_dbg_print_safe( "Kernel : mon accepts dtor, block and signal it \n" ); … … 341 341 // Ctor for monitor guard 342 342 // Sorts monitors before entering 343 void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count, fptr_t func ) libcfa_public {343 void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count, fptr_t func, func_id_t func_id ) libcfa_public { 344 344 thread$ * thrd = active_thread(); 345 345 … … 355 355 356 356 // Update thread context (needed for conditions) 357 (thrd->monitors){m, count, func };357 (thrd->monitors){m, count, func, func_id}; 358 358 359 359 // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count); 360 360 361 361 // Enter the monitors in order 362 __monitor_group_t group = {this.m, this.count, func };362 __monitor_group_t group = {this.m, this.count, func, func_id}; 363 363 enter( group ); 364 364 … … 367 367 368 368 void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count ) libcfa_public { 369 this{ m, count, 0p };369 this{ m, count, 0p, 0 }; 370 370 } 371 371 … … 386 386 // Ctor for monitor guard 387 387 // Sorts monitors before entering 388 void ?{}( monitor_dtor_guard_t & this, monitor$ * m [], fptr_t func, bool join ) libcfa_public {388 void ?{}( monitor_dtor_guard_t & this, monitor$ * m [], fptr_t func, func_id_t func_id, bool join ) libcfa_public { 389 389 // optimization 390 390 thread$ * thrd = active_thread(); … … 400 400 401 401 // Update thread context (needed for conditions) 402 (thrd->monitors){m, 1, func };403 404 __dtor_enter( this.m, func, join );402 (thrd->monitors){m, 1, func, func_id}; 403 404 __dtor_enter( this.m, func, func_id, join ); 405 405 } 406 406 -
libcfa/src/concurrency/monitor.hfa
rc7d106a ra9ce782 48 48 }; 49 49 50 void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count, void (*func)() );50 void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count, void (*func)(), func_id_t func_id ); 51 51 void ?{}( monitor_guard_t & this, monitor$ ** m, __lock_size_t count ); 52 52 void ^?{}( monitor_guard_t & this ); … … 58 58 }; 59 59 60 void ?{}( monitor_dtor_guard_t & this, monitor$ ** m, void (*func)(), bool join );60 void ?{}( monitor_dtor_guard_t & this, monitor$ ** m, void (*func)(), func_id_t func_id, bool join ); 61 61 void ^?{}( monitor_dtor_guard_t & this ); 62 62 -
libcfa/src/concurrency/thread.cfa
rc7d106a ra9ce782 61 61 62 62 doregister(curr_cluster, this); 63 monitors{ &self_mon_p, 1, (fptr_t)0 };63 monitors{ &self_mon_p, 1, (fptr_t)0, (func_id_t)0 }; 64 64 } 65 65 … … 93 93 | { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); }) 94 94 void ?{}( thread_dtor_guard_t & this, 95 T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {95 T & thrd, func_id_t func_id, void(*cancelHandler)(ThreadCancelled(T) &)) { 96 96 monitor$ * m = get_monitor(thrd); 97 97 thread$ * desc = get_thread(thrd); … … 100 100 void (*dtor)(T& mutex this) = ^?{}; 101 101 bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0; 102 (this.mg){&m, (void(*)())dtor, join}; 102 this.func_id = func_id; 103 (this.mg){&m, (void(*)())dtor, func_id, join}; 103 104 104 105 … … 172 173 | { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); }) 173 174 T & join( T & this ) { 174 thread_dtor_guard_t guard = { this, defaultResumptionHandler };175 thread_dtor_guard_t guard = { this, (func_id_t)0, defaultResumptionHandler }; 175 176 return this; 176 177 } -
libcfa/src/concurrency/thread.hfa
rc7d106a ra9ce782 83 83 struct thread_dtor_guard_t { 84 84 monitor_dtor_guard_t mg; 85 func_id_t func_id; 85 86 }; 86 87 87 88 forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled(T)) 88 89 | { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); }) 89 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );90 void ?{}( thread_dtor_guard_t & this, T & thrd, func_id_t func_id, void(*)(ThreadCancelled(T) &) ); 90 91 void ^?{}( thread_dtor_guard_t & this ); 91 92 -
src/Concurrency/Keywords.cpp
rc7d106a ra9ce782 29 29 #include "Common/Examine.hpp" 30 30 #include "Common/Utility.hpp" 31 #include "Concurrency/MutexFuncHash.hpp" 31 32 #include "Common/UniqueName.hpp" 32 33 #include "ControlStruct/LabelGenerator.hpp" … … 1077 1078 1078 1079 // In reverse order: 1079 // monitor_dtor_guard_t __guard = { __monitor, func, f alse };1080 // monitor_dtor_guard_t __guard = { __monitor, func, func_id, false }; 1080 1081 mutBody->push_front( 1081 1082 new ast::DeclStmt( location, new ast::ObjectDecl( … … 1094 1095 generic_func, 1095 1096 ast::ExplicitCast ) ), 1097 new ast::SingleInit( location, 1098 Concurrency::hashMangleExpr( location, func ) ), 1096 1099 new ast::SingleInit( location, 1097 1100 ast::ConstantExpr::from_bool( location, false ) ), … … 1175 1178 ast::ExplicitCast 1176 1179 ) ), 1180 new ast::SingleInit( location, 1181 Concurrency::hashMangleExpr( location, func ) ), 1177 1182 }, 1178 1183 {}, … … 1475 1480 1476 1481 ast::CompoundStmt * MutexKeyword::addThreadDtorStatements( 1477 const ast::FunctionDecl* , const ast::CompoundStmt * body,1482 const ast::FunctionDecl* func, const ast::CompoundStmt * body, 1478 1483 const std::vector<const ast::DeclWithType * > & args ) { 1479 1484 assert( args.size() == 1 ); … … 1487 1492 const CodeLocation & location = mutBody->location; 1488 1493 1489 // thread_dtor_guard_t __guard = { this, intptr( 0 ) };1494 // thread_dtor_guard_t __guard = { this, func_id, intptr( 0 ) }; 1490 1495 mutBody->push_front( new ast::DeclStmt( 1491 1496 location, … … 1500 1505 new ast::CastExpr( location, 1501 1506 new ast::VariableExpr( location, arg ), argType ) ), 1507 new ast::SingleInit( location, 1508 Concurrency::hashMangleExpr( location, func ) ), 1502 1509 new ast::SingleInit( 1503 1510 location, -
src/Concurrency/Waitfor.cpp
rc7d106a ra9ce782 22 22 #include "InitTweak/InitTweak.hpp" 23 23 #include "ResolvExpr/Resolver.hpp" 24 #include "Concurrency/MutexFuncHash.hpp" 24 25 25 26 #include "AST/Print.hpp" … … 331 332 makeAccStmt( location, acceptables, index, "func", 332 333 funcExpr, context ), 334 makeAccStmt( location, acceptables, index, "func_id", 335 Concurrency::hashMangleExpr( location, 336 variableExpr->var.strict_as<ast::DeclWithType>() ), 337 context ), 333 338 makeAccStmt( location, acceptables, index, "data", 334 339 new ast::VariableExpr( location, monitors ), context ), -
src/Validate/Autogen.cpp
rc7d106a ra9ce782 402 402 } 403 403 404 ast::FunctionDecl * decl = genProto( "^?{}", { dst }, {} ); 405 // For concurrent types, remove static storage and inline specifier, and add 406 // cfa_linkonce attribute so the destructor has external linkage with linkonce 407 // semantics. This is required for waitfor to work correctly across translation 408 // units - the function pointer must be the same everywhere, and cfa_linkonce 409 // ensures only one definition survives linking. 410 if ( isConcurrentType() ) { 411 auto mut = ast::mutate( decl ); 412 mut->storage = ast::Storage::Classes(); 413 mut->funcSpec = ast::Function::Specs(); 414 mut->attributes.push_back( new ast::Attribute( "cfa_linkonce" ) ); 415 } 416 return decl; 404 return genProto( "^?{}", { dst }, {} ); 417 405 } 418 406
Note:
See TracChangeset
for help on using the changeset viewer.