Changeset b443db0 for libcfa/src/concurrency
- Timestamp:
- Sep 1, 2022, 10:55:28 AM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 456215a
- Parents:
- f403c46
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/preemption.cfa
rf403c46 rb443db0 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; … … 486 501 487 502 //----------------------------------------------------------------------------- 488 // Some assembly required489 #if defined( __i386 )490 #ifdef __PIC__491 #define RELOC_PRELUDE( label ) \492 "calll .Lcfaasm_prelude_" #label "$pb\n\t" \493 ".Lcfaasm_prelude_" #label "$pb:\n\t" \494 "popl %%eax\n\t" \495 ".Lcfaasm_prelude_" #label "_end:\n\t" \496 "addl $_GLOBAL_OFFSET_TABLE_+(.Lcfaasm_prelude_" #label "_end-.Lcfaasm_prelude_" #label "$pb), %%eax\n\t"497 #define RELOC_PREFIX ""498 #define RELOC_SUFFIX "@GOT(%%eax)"499 #else500 #define RELOC_PREFIX "$"501 #define RELOC_SUFFIX ""502 #endif503 #define __cfaasm_label( label ) struct asm_region label = \504 ({ \505 struct asm_region region; \506 asm( \507 RELOC_PRELUDE( label ) \508 "movl " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \509 "movl " RELOC_PREFIX "__cfaasm_" #label "_after" RELOC_SUFFIX ", %[va]\n\t" \510 : [vb]"=r"(region.before), [va]"=r"(region.after) \511 ); \512 region; \513 });514 #elif defined( __x86_64 )515 #ifdef __PIC__516 #define RELOC_PREFIX ""517 #define RELOC_SUFFIX "@GOTPCREL(%%rip)"518 #else519 #define RELOC_PREFIX "$"520 #define RELOC_SUFFIX ""521 #endif522 #define __cfaasm_label( label ) struct asm_region label = \523 ({ \524 struct asm_region region; \525 asm( \526 "movq " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \527 "movq " RELOC_PREFIX "__cfaasm_" #label "_after" RELOC_SUFFIX ", %[va]\n\t" \528 : [vb]"=r"(region.before), [va]"=r"(region.after) \529 ); \530 region; \531 });532 #elif defined( __aarch64__ )533 #ifdef __PIC__534 // Note that this works only for gcc535 #define __cfaasm_label( label ) struct asm_region label = \536 ({ \537 struct asm_region region; \538 asm( \539 "adrp %[vb], _GLOBAL_OFFSET_TABLE_" "\n\t" \540 "ldr %[vb], [%[vb], #:gotpage_lo15:__cfaasm_" #label "_before]" "\n\t" \541 "adrp %[va], _GLOBAL_OFFSET_TABLE_" "\n\t" \542 "ldr %[va], [%[va], #:gotpage_lo15:__cfaasm_" #label "_after]" "\n\t" \543 : [vb]"=r"(region.before), [va]"=r"(region.after) \544 ); \545 region; \546 });547 #else548 #error this is not the right thing to do549 /*550 #define __cfaasm_label( label ) struct asm_region label = \551 ({ \552 struct asm_region region; \553 asm( \554 "adrp %[vb], __cfaasm_" #label "_before" "\n\t" \555 "add %[vb], %[vb], :lo12:__cfaasm_" #label "_before" "\n\t" \556 "adrp %[va], :got:__cfaasm_" #label "_after" "\n\t" \557 "add %[va], %[va], :lo12:__cfaasm_" #label "_after" "\n\t" \558 : [vb]"=r"(region.before), [va]"=r"(region.after) \559 ); \560 region; \561 });562 */563 #endif564 #else565 #error unknown hardware architecture566 #endif567 568 503 // KERNEL ONLY 569 504 // Check if a __cfactx_switch signal handler shoud defer … … 571 506 // If false : preemption is unsafe and marked as pending 572 507 static inline bool preemption_ready( void * ip ) { 573 // Get all the region for which it is not safe to preempt574 __cfaasm_label( get );575 __cfaasm_label( check );576 __cfaasm_label( dsable );577 // __cfaasm_label( debug );578 579 508 // Check if preemption is safe 580 509 bool ready = true; 581 if( __cfaasm_in( ip, get ) ) { ready = false; goto EXIT; }; 582 if( __cfaasm_in( ip, check ) ) { ready = false; goto EXIT; }; 583 if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; }; 584 // 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 585 513 if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; }; 586 514 if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
Note: See TracChangeset
for help on using the changeset viewer.