Ignore:
Timestamp:
Sep 19, 2022, 8:11:02 PM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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.
Message:

fix merge conflict

File:
1 edited

Legend:

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

    rebf8ca5 r23a08aa0  
    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;
     
    358373                }
    359374        }
     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        }
    360398}
    361399
     
    463501
    464502//-----------------------------------------------------------------------------
    465 // Some assembly required
    466 #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         #else
    477                 #define RELOC_PREFIX "$"
    478                 #define RELOC_SUFFIX ""
    479         #endif
    480         #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         #else
    496                 #define RELOC_PREFIX "$"
    497                 #define RELOC_SUFFIX ""
    498         #endif
    499         #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 gcc
    512                 #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         #else
    525                 #error this is not the right thing to do
    526                 /*
    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         #endif
    541 #else
    542         #error unknown hardware architecture
    543 #endif
    544 
    545503// KERNEL ONLY
    546504// Check if a __cfactx_switch signal handler shoud defer
     
    548506// If false : preemption is unsafe and marked as pending
    549507static inline bool preemption_ready( void * ip ) {
    550         // Get all the region for which it is not safe to preempt
    551         __cfaasm_label( get    );
    552         __cfaasm_label( check  );
    553         __cfaasm_label( dsable );
    554         // __cfaasm_label( debug  );
    555 
    556508        // Check if preemption is safe
    557509        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
    562513        if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
    563514        if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
     
    643594// Kernel Signal Handlers
    644595//=============================================================================================
    645 __cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
     596__cfaabi_dbg_debug_do( static __thread void * last_interrupt = 0; )
    646597
    647598// Context switch signal handler
Note: See TracChangeset for help on using the changeset viewer.