Changeset 23a08aa0 for libcfa/src/concurrency/preemption.cfa
- Timestamp:
- Sep 19, 2022, 8:11:02 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- aa9f215
- Parents:
- ebf8ca5 (diff), ae1d151 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/preemption.cfa
rebf8ca5 r23a08aa0 238 238 //---------- 239 239 // special case for preemption since used often 240 __attribute__((optimize("no-reorder-blocks"))) bool __preemption_enabled() libcfa_ public {240 __attribute__((optimize("no-reorder-blocks"))) bool __preemption_enabled() libcfa_nopreempt libcfa_public { 241 241 // create a assembler label before 242 242 // marked as clobber all to avoid movement … … 272 272 } 273 273 274 extern "C" { 275 __attribute__((visibility("hidden"))) extern void * const __start_cfatext_nopreempt; 276 __attribute__((visibility("hidden"))) extern void * const __stop_cfatext_nopreempt; 277 278 extern const __cfa_nopreempt_region __libcfa_nopreempt; 279 __attribute__((visibility("protected"))) const __cfa_nopreempt_region __libcfathrd_nopreempt @= { 280 (void * const)&__start_cfatext_nopreempt, 281 (void * const)&__stop_cfatext_nopreempt 282 }; 283 } 284 285 static inline bool __cfaabi_in( void * const ip, const struct __cfa_nopreempt_region & const region ) { 286 return ip >= region.start && ip <= region.stop; 287 } 288 274 289 275 290 //---------- 276 291 // Get data from the TLS block 277 292 // struct asm_region __cfaasm_get; 278 uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__, visibility("default"))); //no inline to avoid problems293 uintptr_t __cfatls_get( unsigned long int offset ) libcfa_nopreempt libcfa_public; //no inline to avoid problems 279 294 uintptr_t __cfatls_get( unsigned long int offset ) { 280 295 // create a assembler label before … … 295 310 extern "C" { 296 311 // Disable interrupts by incrementing the counter 297 __attribute__((__noinline__, visibility("default"))) void disable_interrupts()libcfa_public {312 void disable_interrupts() libcfa_nopreempt libcfa_public { 298 313 // create a assembler label before 299 314 // marked as clobber all to avoid movement … … 326 341 // Enable interrupts by decrementing the counter 327 342 // If counter reaches 0, execute any pending __cfactx_switch 328 void enable_interrupts( bool poll ) libcfa_ public {343 void enable_interrupts( bool poll ) libcfa_nopreempt libcfa_public { 329 344 // Cache the processor now since interrupts can start happening after the atomic store 330 345 processor * proc = __cfaabi_tls.this_processor; … … 358 373 } 359 374 } 375 376 // Check whether or not there is pending preemption 377 // force_yield( __POLL_PREEMPTION ) if appropriate 378 // return true if the thread was in an interruptable state 379 // i.e. on a real processor and not in the kernel 380 // (can return true even if no preemption was pending) 381 bool poll_interrupts() libcfa_public { 382 // Cache the processor now since interrupts can start happening after the atomic store 383 processor * proc = publicTLS_get( this_processor ); 384 if ( ! proc ) return false; 385 if ( ! __preemption_enabled() ) return false; 386 387 with( __cfaabi_tls.preemption_state ){ 388 // Signal the compiler that a fence is needed but only for signal handlers 389 __atomic_signal_fence(__ATOMIC_RELEASE); 390 if( proc->pending_preemption ) { 391 proc->pending_preemption = false; 392 force_yield( __POLL_PREEMPTION ); 393 } 394 } 395 396 return true; 397 } 360 398 } 361 399 … … 463 501 464 502 //----------------------------------------------------------------------------- 465 // Some assembly required466 #if defined( __i386 )467 #ifdef __PIC__468 #define RELOC_PRELUDE( label ) \469 "calll .Lcfaasm_prelude_" #label "$pb\n\t" \470 ".Lcfaasm_prelude_" #label "$pb:\n\t" \471 "popl %%eax\n\t" \472 ".Lcfaasm_prelude_" #label "_end:\n\t" \473 "addl $_GLOBAL_OFFSET_TABLE_+(.Lcfaasm_prelude_" #label "_end-.Lcfaasm_prelude_" #label "$pb), %%eax\n\t"474 #define RELOC_PREFIX ""475 #define RELOC_SUFFIX "@GOT(%%eax)"476 #else477 #define RELOC_PREFIX "$"478 #define RELOC_SUFFIX ""479 #endif480 #define __cfaasm_label( label ) struct asm_region label = \481 ({ \482 struct asm_region region; \483 asm( \484 RELOC_PRELUDE( label ) \485 "movl " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \486 "movl " RELOC_PREFIX "__cfaasm_" #label "_after" RELOC_SUFFIX ", %[va]\n\t" \487 : [vb]"=r"(region.before), [va]"=r"(region.after) \488 ); \489 region; \490 });491 #elif defined( __x86_64 )492 #ifdef __PIC__493 #define RELOC_PREFIX ""494 #define RELOC_SUFFIX "@GOTPCREL(%%rip)"495 #else496 #define RELOC_PREFIX "$"497 #define RELOC_SUFFIX ""498 #endif499 #define __cfaasm_label( label ) struct asm_region label = \500 ({ \501 struct asm_region region; \502 asm( \503 "movq " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \504 "movq " RELOC_PREFIX "__cfaasm_" #label "_after" RELOC_SUFFIX ", %[va]\n\t" \505 : [vb]"=r"(region.before), [va]"=r"(region.after) \506 ); \507 region; \508 });509 #elif defined( __aarch64__ )510 #ifdef __PIC__511 // Note that this works only for gcc512 #define __cfaasm_label( label ) struct asm_region label = \513 ({ \514 struct asm_region region; \515 asm( \516 "adrp %[vb], _GLOBAL_OFFSET_TABLE_" "\n\t" \517 "ldr %[vb], [%[vb], #:gotpage_lo15:__cfaasm_" #label "_before]" "\n\t" \518 "adrp %[va], _GLOBAL_OFFSET_TABLE_" "\n\t" \519 "ldr %[va], [%[va], #:gotpage_lo15:__cfaasm_" #label "_after]" "\n\t" \520 : [vb]"=r"(region.before), [va]"=r"(region.after) \521 ); \522 region; \523 });524 #else525 #error this is not the right thing to do526 /*527 #define __cfaasm_label( label ) struct asm_region label = \528 ({ \529 struct asm_region region; \530 asm( \531 "adrp %[vb], __cfaasm_" #label "_before" "\n\t" \532 "add %[vb], %[vb], :lo12:__cfaasm_" #label "_before" "\n\t" \533 "adrp %[va], :got:__cfaasm_" #label "_after" "\n\t" \534 "add %[va], %[va], :lo12:__cfaasm_" #label "_after" "\n\t" \535 : [vb]"=r"(region.before), [va]"=r"(region.after) \536 ); \537 region; \538 });539 */540 #endif541 #else542 #error unknown hardware architecture543 #endif544 545 503 // KERNEL ONLY 546 504 // Check if a __cfactx_switch signal handler shoud defer … … 548 506 // If false : preemption is unsafe and marked as pending 549 507 static inline bool preemption_ready( void * ip ) { 550 // Get all the region for which it is not safe to preempt551 __cfaasm_label( get );552 __cfaasm_label( check );553 __cfaasm_label( dsable );554 // __cfaasm_label( debug );555 556 508 // Check if preemption is safe 557 509 bool ready = true; 558 if( __cfaasm_in( ip, get ) ) { ready = false; goto EXIT; }; 559 if( __cfaasm_in( ip, check ) ) { ready = false; goto EXIT; }; 560 if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; }; 561 // if( __cfaasm_in( ip, debug ) ) { ready = false; goto EXIT; }; 510 if( __cfaabi_in( ip, __libcfa_nopreempt ) ) { ready = false; goto EXIT; }; 511 if( __cfaabi_in( ip, __libcfathrd_nopreempt ) ) { ready = false; goto EXIT; }; 512 562 513 if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; }; 563 514 if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; }; … … 643 594 // Kernel Signal Handlers 644 595 //============================================================================================= 645 __cfaabi_dbg_debug_do( static thread_localvoid * last_interrupt = 0; )596 __cfaabi_dbg_debug_do( static __thread void * last_interrupt = 0; ) 646 597 647 598 // Context switch signal handler
Note:
See TracChangeset
for help on using the changeset viewer.