Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/cluster.cfa

    ra8667ab rf5f2768  
    6969}
    7070
     71#if   defined(CFA_HAVE_LINUX_LIBRSEQ)
     72        // No forward declaration needed
     73        #define __kernel_rseq_register rseq_register_current_thread
     74        #define __kernel_rseq_unregister rseq_unregister_current_thread
     75#elif defined(CFA_HAVE_LINUX_RSEQ_H)
     76        static void __kernel_raw_rseq_register  (void);
     77        static void __kernel_raw_rseq_unregister(void);
     78
     79        #define __kernel_rseq_register __kernel_raw_rseq_register
     80        #define __kernel_rseq_unregister __kernel_raw_rseq_unregister
     81#else
     82        // No forward declaration needed
     83        // No initialization needed
     84        static inline void noop(void) {}
     85
     86        #define __kernel_rseq_register noop
     87        #define __kernel_rseq_unregister noop
     88#endif
     89
    7190//=======================================================================
    7291// Cluster wide reader-writer lock
     
    91110// Lock-Free registering/unregistering of threads
    92111unsigned register_proc_id( void ) with(__scheduler_lock.lock) {
     112        __kernel_rseq_register();
     113
    93114        bool * handle = (bool *)&kernelTLS().sched_lock;
    94115
     
    140161
    141162        __atomic_store_n(cell, 0p, __ATOMIC_RELEASE);
     163
     164        __kernel_rseq_unregister();
    142165}
    143166
     
    481504        /* paranoid */ verify( mock_head(this)    == this.l.prev );
    482505}
     506
     507#if   defined(CFA_HAVE_LINUX_LIBRSEQ)
     508        // No definition needed
     509#elif defined(CFA_HAVE_LINUX_RSEQ_H)
     510
     511        #if defined( __x86_64 ) || defined( __i386 )
     512                #define RSEQ_SIG        0x53053053
     513        #elif defined( __ARM_ARCH )
     514                #ifdef __ARMEB__
     515                #define RSEQ_SIG    0xf3def5e7      /* udf    #24035    ; 0x5de3 (ARMv6+) */
     516                #else
     517                #define RSEQ_SIG    0xe7f5def3      /* udf    #24035    ; 0x5de3 */
     518                #endif
     519        #endif
     520
     521        extern void __disable_interrupts_hard();
     522        extern void __enable_interrupts_hard();
     523
     524        static void __kernel_raw_rseq_register  (void) {
     525                /* paranoid */ verify( __cfaabi_rseq.cpu_id == RSEQ_CPU_ID_UNINITIALIZED );
     526
     527                // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, (sigset_t *)0p, _NSIG / 8);
     528                int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, RSEQ_SIG);
     529                if(ret != 0) {
     530                        int e = errno;
     531                        switch(e) {
     532                        case EINVAL: abort("KERNEL ERROR: rseq register invalid argument");
     533                        case ENOSYS: abort("KERNEL ERROR: rseq register no supported");
     534                        case EFAULT: abort("KERNEL ERROR: rseq register with invalid argument");
     535                        case EBUSY : abort("KERNEL ERROR: rseq register already registered");
     536                        case EPERM : abort("KERNEL ERROR: rseq register sig  argument  on unregistration does not match the signature received on registration");
     537                        default: abort("KERNEL ERROR: rseq register unexpected return %d", e);
     538                        }
     539                }
     540        }
     541
     542        static void __kernel_raw_rseq_unregister(void) {
     543                /* paranoid */ verify( __cfaabi_rseq.cpu_id >= 0 );
     544
     545                // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, (sigset_t *)0p, _NSIG / 8);
     546                int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
     547                if(ret != 0) {
     548                        int e = errno;
     549                        switch(e) {
     550                        case EINVAL: abort("KERNEL ERROR: rseq unregister invalid argument");
     551                        case ENOSYS: abort("KERNEL ERROR: rseq unregister no supported");
     552                        case EFAULT: abort("KERNEL ERROR: rseq unregister with invalid argument");
     553                        case EBUSY : abort("KERNEL ERROR: rseq unregister already registered");
     554                        case EPERM : abort("KERNEL ERROR: rseq unregister sig  argument  on unregistration does not match the signature received on registration");
     555                        default: abort("KERNEL ERROR: rseq unregisteunexpected return %d", e);
     556                        }
     557                }
     558        }
     559#else
     560        // No definition needed
     561#endif
Note: See TracChangeset for help on using the changeset viewer.