Changeset 82a2fed


Ignore:
Timestamp:
Nov 10, 2020, 12:44:22 PM (11 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
b82d140
Parents:
54dcab1
Message:

Changed preemption to use code sections rather than atomic access to TLS.

Location:
libcfa/src/concurrency
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/fwd.hfa

    r54dcab1 r82a2fed  
    6565
    6666                extern uintptr_t __cfatls_get( unsigned long int member );
    67                 // #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
    68                 #define publicTLS_get( member ) (__cfaabi_tls.member)
    69                 // extern forall(otype T) T __cfatls_get( T * member, T value );
    70                 // #define publicTLS_set( member, value ) __cfatls_set( (typeof(member)*)__builtin_offsetof(KernelThreadData, member), value );
     67                #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
    7168
    7269                static inline uint64_t __tls_rand() {
  • libcfa/src/concurrency/preemption.cfa

    r54dcab1 r82a2fed  
    231231}
    232232
     233struct asm_region {
     234        void * before;
     235        void * after;
     236};
     237
     238static inline bool __cfaasm_in( void * ip, struct asm_region & region ) {
     239        return ip >= region.before && ip <= region.after;
     240}
     241
     242
    233243//----------
    234244// Get data from the TLS block
     245// struct asm_region __cfaasm_get;
    235246uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__)); //no inline to avoid problems
    236247uintptr_t __cfatls_get( unsigned long int offset ) {
     248        // __cfaasm_get.before = ({ void * value; asm("movq $__cfaasm_get_before, %[v]\n\t" : [v]"=r"(value) ); value; });
     249        // __cfaasm_get.after  = ({ void * value; asm("movq $__cfaasm_get_after , %[v]\n\t" : [v]"=r"(value) ); value; });
    237250        // create a assembler label before
    238251        // marked as clobber all to avoid movement
     
    253266                // create a assembler label before
    254267                // marked as clobber all to avoid movement
    255                 asm volatile("__cfaasm_disable_before:":::"memory");
     268                asm volatile("__cfaasm_dsable_before:":::"memory");
    256269
    257270                with( __cfaabi_tls.preemption_state ) {
     
    275288                // create a assembler label after
    276289                // marked as clobber all to avoid movement
    277                 asm volatile("__cfaasm_disable_after:":::"memory");
     290                asm volatile("__cfaasm_dsable_after:":::"memory");
    278291        }
    279292
     
    283296                // create a assembler label before
    284297                // marked as clobber all to avoid movement
    285                 asm volatile("__cfaasm_enable_before:":::"memory");
     298                asm volatile("__cfaasm_enble_before:":::"memory");
    286299
    287300                processor   * proc = __cfaabi_tls.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
     
    318331                // create a assembler label after
    319332                // marked as clobber all to avoid movement
    320                 asm volatile("__cfaasm_enable_after:":::"memory");
     333                asm volatile("__cfaasm_enble_after:":::"memory");
    321334        }
    322335
     
    386399}
    387400
     401//-----------------------------------------------------------------------------
     402// Some assembly required
     403#if defined( __i386 )
     404        #ifdef __PIC__
     405                #define RELOC_PRELUDE( label ) \
     406                        "calll   .Lcfaasm_prelude_" #label "$pb\n\t" \
     407                        ".Lcfaasm_prelude_" #label "$pb:\n\t" \
     408                        "popl    %%eax\n\t" \
     409                        ".Lcfaasm_prelude_" #label "_end:\n\t" \
     410                        "addl    $_GLOBAL_OFFSET_TABLE_+(.Lcfaasm_prelude_" #label "_end-.Lcfaasm_prelude_" #label "$pb), %%eax\n\t"
     411                #define RELOC_PREFIX ""
     412                #define RELOC_SUFFIX "@GOT(%%eax)"
     413        #else
     414                #define RELOC_PREFIX "$"
     415                #define RELOC_SUFFIX ""
     416        #endif
     417        #define __cfaasm_label( label ) static struct asm_region label = \
     418                ({ \
     419                        struct asm_region region; \
     420                        asm( \
     421                                RELOC_PRELUDE( label ) \
     422                                "movl " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \
     423                                "movl " RELOC_PREFIX "__cfaasm_" #label "_after"  RELOC_SUFFIX ", %[va]\n\t" \
     424                                 : [vb]"=r"(region.before), [va]"=r"(region.after) \
     425                        ); \
     426                        region; \
     427                });
     428#elif defined( __x86_64 )
     429        #ifdef __PIC__
     430                #define RELOC_PREFIX ""
     431                #define RELOC_SUFFIX "@GOTPCREL(%%rip)"
     432        #else
     433                #define RELOC_PREFIX "$"
     434                #define RELOC_SUFFIX ""
     435        #endif
     436        #define __cfaasm_label( label ) static struct asm_region label = \
     437                ({ \
     438                        struct asm_region region; \
     439                        asm( \
     440                                "movq " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \
     441                                "movq " RELOC_PREFIX "__cfaasm_" #label "_after"  RELOC_SUFFIX ", %[va]\n\t" \
     442                                 : [vb]"=r"(region.before), [va]"=r"(region.after) \
     443                        ); \
     444                        region; \
     445                });
     446#elif defined( __aarch64__ )
     447        #ifdef __PIC__
     448                #define RELOC_TAG "@PLT"
     449        #else
     450                #define RELOC_TAG ""
     451        #endif
     452        #define __cfaasm_label( label ) \
     453                ({ \
     454                        struct asm_region region; \
     455                        asm( \
     456                                "mov %[vb], __cfaasm_" #label "_before@GOTPCREL(%%rip)"  "\n\t" \
     457                                "mov %[va], __cfaasm_" #label "_after@GOTPCREL(%%rip)"   "\n\t" \
     458                                 : [vb]"=r"(region.before), [va]"=r"(region.after) \
     459                        ); \
     460                        region; \
     461                });
     462#else
     463        #error unknown hardware architecture
     464#endif
     465
    388466// KERNEL ONLY
    389467// Check if a __cfactx_switch signal handler shoud defer
    390468// If true  : preemption is safe
    391469// If false : preemption is unsafe and marked as pending
    392 static inline bool preemption_ready() {
     470static inline bool preemption_ready( void * ip ) {
     471        // Get all the region for which it is not safe to preempt
     472        __cfaasm_label( get    );
     473        __cfaasm_label( check  );
     474        __cfaasm_label( dsable );
     475        __cfaasm_label( enble );
     476        __cfaasm_label( nopoll );
     477
    393478        // Check if preemption is safe
    394         bool ready = __cfaabi_tls.preemption_state.enabled && ! __cfaabi_tls.preemption_state.in_progress;
    395 
     479        bool ready = true;
     480        if( __cfaasm_in( ip, get    ) ) { ready = false; goto EXIT; };
     481        if( __cfaasm_in( ip, check  ) ) { ready = false; goto EXIT; };
     482        if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; };
     483        if( __cfaasm_in( ip, enble  ) ) { ready = false; goto EXIT; };
     484        if( __cfaasm_in( ip, nopoll ) ) { ready = false; goto EXIT; };
     485        if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
     486        if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
     487
     488EXIT:
    396489        // Adjust the pending flag accordingly
    397490        __cfaabi_tls.this_processor->pending_preemption = !ready;
     
    468561// Kernel Signal Handlers
    469562//=============================================================================================
    470 struct asm_region {
    471         void * before;
    472         void * after;
    473 };
    474 
    475 //-----------------------------------------------------------------------------
    476 // Some assembly required
    477 #if defined( __i386 )
    478         #define __cfaasm_label( label ) \
    479                 ({ \
    480                         struct asm_region region; \
    481                         asm( \
    482                                 "movl $__cfaasm_" #label "_before, %[vb]\n\t" \
    483                                 "movl $__cfaasm_" #label "_after , %[va]\n\t" \
    484                                  : [vb]"=r"(region.before), [vb]"=r"(region.before) \
    485                         ); \
    486                         region; \
    487                 });
    488 #elif defined( __x86_64 )
    489         #ifdef __PIC__
    490                 #define PLT "@PLT"
    491         #else
    492                 #define PLT ""
    493         #endif
    494         #define __cfaasm_label( label ) \
    495                 ({ \
    496                         struct asm_region region; \
    497                         asm( \
    498                                 "movq $__cfaasm_" #label "_before" PLT ", %[vb]\n\t" \
    499                                 "movq $__cfaasm_" #label "_after"  PLT ", %[va]\n\t" \
    500                                  : [vb]"=r"(region.before), [va]"=r"(region.after) \
    501                         ); \
    502                         region; \
    503                 });
    504 #elif defined( __aarch64__ )
    505         #error __cfaasm_label undefined for arm
    506 #else
    507         #error unknown hardware architecture
    508 #endif
    509 
    510563__cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
    511564
     
    530583
    531584        // Check if it is safe to preempt here
    532         if( !preemption_ready() ) { return; }
    533 
    534         struct asm_region region;
    535         region = __cfaasm_label( get     ); if( ip >= region.before && ip <= region.after ) return;
    536         region = __cfaasm_label( check   ); if( ip >= region.before && ip <= region.after ) return;
    537         region = __cfaasm_label( disable ); if( ip >= region.before && ip <= region.after ) return;
    538         region = __cfaasm_label( enable  ); if( ip >= region.before && ip <= region.after ) return;
    539         region = __cfaasm_label( nopoll  ); if( ip >= region.before && ip <= region.after ) return;
     585        if( !preemption_ready( ip ) ) { return; }
    540586
    541587        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p @ %p).\n", __cfaabi_tls.this_processor, __cfaabi_tls.this_thread, (void *)(cxt->uc_mcontext.CFA_REG_IP) );
Note: See TracChangeset for help on using the changeset viewer.