Ignore:
Timestamp:
Sep 1, 2022, 10:55:28 AM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
456215a
Parents:
f403c46
Message:

Change how no preempts zone are implemented. From begin/end tags to specific sections.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/preemption.cfa

    rf403c46 rb443db0  
    238238//----------
    239239// 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 {
    241241        // create a assembler label before
    242242        // marked as clobber all to avoid movement
     
    272272}
    273273
     274extern "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
     285static inline bool __cfaabi_in( void * const ip, const struct __cfa_nopreempt_region & const region ) {
     286        return ip >= region.start && ip <= region.stop;
     287}
     288
    274289
    275290//----------
    276291// Get data from the TLS block
    277292// struct asm_region __cfaasm_get;
    278 uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__, visibility("default"))); //no inline to avoid problems
     293uintptr_t __cfatls_get( unsigned long int offset ) libcfa_nopreempt libcfa_public; //no inline to avoid problems
    279294uintptr_t __cfatls_get( unsigned long int offset ) {
    280295        // create a assembler label before
     
    295310extern "C" {
    296311        // Disable interrupts by incrementing the counter
    297         __attribute__((__noinline__, visibility("default"))) void disable_interrupts() libcfa_public {
     312        void disable_interrupts() libcfa_nopreempt libcfa_public {
    298313                // create a assembler label before
    299314                // marked as clobber all to avoid movement
     
    326341        // Enable interrupts by decrementing the counter
    327342        // 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 {
    329344                // Cache the processor now since interrupts can start happening after the atomic store
    330345                processor   * proc = __cfaabi_tls.this_processor;
     
    486501
    487502//-----------------------------------------------------------------------------
    488 // Some assembly required
    489 #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         #else
    500                 #define RELOC_PREFIX "$"
    501                 #define RELOC_SUFFIX ""
    502         #endif
    503         #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         #else
    519                 #define RELOC_PREFIX "$"
    520                 #define RELOC_SUFFIX ""
    521         #endif
    522         #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 gcc
    535                 #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         #else
    548                 #error this is not the right thing to do
    549                 /*
    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         #endif
    564 #else
    565         #error unknown hardware architecture
    566 #endif
    567 
    568503// KERNEL ONLY
    569504// Check if a __cfactx_switch signal handler shoud defer
     
    571506// If false : preemption is unsafe and marked as pending
    572507static inline bool preemption_ready( void * ip ) {
    573         // Get all the region for which it is not safe to preempt
    574         __cfaasm_label( get    );
    575         __cfaasm_label( check  );
    576         __cfaasm_label( dsable );
    577         // __cfaasm_label( debug  );
    578 
    579508        // Check if preemption is safe
    580509        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
    585513        if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
    586514        if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
Note: See TracChangeset for help on using the changeset viewer.