Ignore:
Timestamp:
Jun 29, 2021, 5:35:19 PM (3 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
dcad80a
Parents:
5a46e09 (diff), d02e547 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

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

    r5a46e09 r660665f  
    1515
    1616#define __cforall_thread__
     17#define _GNU_SOURCE
     18
    1719// #define __CFA_DEBUG_PRINT_READY_QUEUE__
    1820
     
    2022#define USE_RELAXED_FIFO
    2123// #define USE_WORK_STEALING
     24// #define USE_CPU_WORK_STEALING
    2225
    2326#include "bits/defs.hfa"
     27#include "device/cpu.hfa"
    2428#include "kernel_private.hfa"
    2529
    26 #define _GNU_SOURCE
    2730#include "stdlib.hfa"
    2831#include "math.hfa"
    2932
     33#include <errno.h>
    3034#include <unistd.h>
     35
     36extern "C" {
     37        #include <sys/syscall.h>  // __NR_xxx
     38}
    3139
    3240#include "ready_subqueue.hfa"
     
    4654#endif
    4755
    48 #if   defined(USE_RELAXED_FIFO)
     56#if   defined(USE_CPU_WORK_STEALING)
     57        #define READYQ_SHARD_FACTOR 2
     58#elif defined(USE_RELAXED_FIFO)
    4959        #define BIAS 4
    5060        #define READYQ_SHARD_FACTOR 4
     
    8595}
    8696
     97#if   defined(CFA_HAVE_LINUX_LIBRSEQ)
     98        // No forward declaration needed
     99        #define __kernel_rseq_register rseq_register_current_thread
     100        #define __kernel_rseq_unregister rseq_unregister_current_thread
     101#elif defined(CFA_HAVE_LINUX_RSEQ_H)
     102        void __kernel_raw_rseq_register  (void);
     103        void __kernel_raw_rseq_unregister(void);
     104
     105        #define __kernel_rseq_register __kernel_raw_rseq_register
     106        #define __kernel_rseq_unregister __kernel_raw_rseq_unregister
     107#else
     108        // No forward declaration needed
     109        // No initialization needed
     110        static inline void noop(void) {}
     111
     112        #define __kernel_rseq_register noop
     113        #define __kernel_rseq_unregister noop
     114#endif
     115
    87116//=======================================================================
    88117// Cluster wide reader-writer lock
     
    107136// Lock-Free registering/unregistering of threads
    108137unsigned register_proc_id( void ) with(*__scheduler_lock) {
     138        __kernel_rseq_register();
     139
    109140        __cfadbg_print_safe(ready_queue, "Kernel : Registering proc %p for RW-Lock\n", proc);
    110141        bool * handle = (bool *)&kernelTLS().sched_lock;
     
    161192
    162193        __cfadbg_print_safe(ready_queue, "Kernel : Unregister proc %p\n", proc);
     194
     195        __kernel_rseq_unregister();
    163196}
    164197
     
    214247//=======================================================================
    215248void ?{}(__ready_queue_t & this) with (this) {
    216         lanes.data  = 0p;
    217         lanes.tscs  = 0p;
    218         lanes.count = 0;
     249        #if defined(USE_CPU_WORK_STEALING)
     250                lanes.count = cpu_info.hthrd_count * READYQ_SHARD_FACTOR;
     251                lanes.data = alloc( lanes.count );
     252                lanes.tscs = alloc( lanes.count );
     253
     254                for( idx; (size_t)lanes.count ) {
     255                        (lanes.data[idx]){};
     256                        lanes.tscs[idx].tv = rdtscl();
     257                }
     258        #else
     259                lanes.data  = 0p;
     260                lanes.tscs  = 0p;
     261                lanes.count = 0;
     262        #endif
    219263}
    220264
    221265void ^?{}(__ready_queue_t & this) with (this) {
    222         verify( SEQUENTIAL_SHARD == lanes.count );
     266        #if !defined(USE_CPU_WORK_STEALING)
     267                verify( SEQUENTIAL_SHARD == lanes.count );
     268        #endif
     269
    223270        free(lanes.data);
    224271        free(lanes.tscs);
     
    226273
    227274//-----------------------------------------------------------------------
     275#if defined(USE_CPU_WORK_STEALING)
     276        __attribute__((hot)) void push(struct cluster * cltr, struct $thread * thrd, bool push_local) with (cltr->ready_queue) {
     277                __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr);
     278
     279                processor * const proc = kernelTLS().this_processor;
     280                const bool external = !push_local || (!proc) || (cltr != proc->cltr);
     281
     282                const int cpu = __kernel_getcpu();
     283                /* paranoid */ verify(cpu >= 0);
     284                /* paranoid */ verify(cpu < cpu_info.hthrd_count);
     285                /* paranoid */ verify(cpu * READYQ_SHARD_FACTOR < lanes.count);
     286
     287                const cpu_map_entry_t & map = cpu_info.llc_map[cpu];
     288                /* paranoid */ verify(map.start * READYQ_SHARD_FACTOR < lanes.count);
     289                /* paranoid */ verify(map.self * READYQ_SHARD_FACTOR < lanes.count);
     290                /* paranoid */ verifyf((map.start + map.count) * READYQ_SHARD_FACTOR <= lanes.count, "have %zu lanes but map can go up to %u", lanes.count, (map.start + map.count) * READYQ_SHARD_FACTOR);
     291
     292                const int start = map.self * READYQ_SHARD_FACTOR;
     293                unsigned i;
     294                do {
     295                        unsigned r;
     296                        if(unlikely(external)) { r = __tls_rand(); }
     297                        else { r = proc->rdq.its++; }
     298                        i = start + (r % READYQ_SHARD_FACTOR);
     299                        // If we can't lock it retry
     300                } while( !__atomic_try_acquire( &lanes.data[i].lock ) );
     301
     302                // Actually push it
     303                push(lanes.data[i], thrd);
     304
     305                // Unlock and return
     306                __atomic_unlock( &lanes.data[i].lock );
     307
     308                #if !defined(__CFA_NO_STATISTICS__)
     309                        if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.success, 1, __ATOMIC_RELAXED);
     310                        else __tls_stats()->ready.push.local.success++;
     311                #endif
     312
     313                __cfadbg_print_safe(ready_queue, "Kernel : Pushed %p on cluster %p (idx: %u, mask %llu, first %d)\n", thrd, cltr, i, used.mask[0], lane_first);
     314
     315        }
     316
     317        // Pop from the ready queue from a given cluster
     318        __attribute__((hot)) $thread * pop_fast(struct cluster * cltr) with (cltr->ready_queue) {
     319                /* paranoid */ verify( lanes.count > 0 );
     320                /* paranoid */ verify( kernelTLS().this_processor );
     321
     322                const int cpu = __kernel_getcpu();
     323                /* paranoid */ verify(cpu >= 0);
     324                /* paranoid */ verify(cpu < cpu_info.hthrd_count);
     325                /* paranoid */ verify(cpu * READYQ_SHARD_FACTOR < lanes.count);
     326
     327                const cpu_map_entry_t & map = cpu_info.llc_map[cpu];
     328                /* paranoid */ verify(map.start * READYQ_SHARD_FACTOR < lanes.count);
     329                /* paranoid */ verify(map.self * READYQ_SHARD_FACTOR < lanes.count);
     330                /* paranoid */ verifyf((map.start + map.count) * READYQ_SHARD_FACTOR <= lanes.count, "have %zu lanes but map can go up to %u", lanes.count, (map.start + map.count) * READYQ_SHARD_FACTOR);
     331
     332                processor * const proc = kernelTLS().this_processor;
     333                const int start = map.self * READYQ_SHARD_FACTOR;
     334
     335                // Did we already have a help target
     336                if(proc->rdq.target == -1u) {
     337                        // if We don't have a
     338                        unsigned long long min = ts(lanes.data[start]);
     339                        for(i; READYQ_SHARD_FACTOR) {
     340                                unsigned long long tsc = ts(lanes.data[start + i]);
     341                                if(tsc < min) min = tsc;
     342                        }
     343                        proc->rdq.cutoff = min;
     344
     345                        /* paranoid */ verify(lanes.count < 65536); // The following code assumes max 65536 cores.
     346                        /* paranoid */ verify(map.count < 65536); // The following code assumes max 65536 cores.
     347                        uint64_t chaos = __tls_rand();
     348                        uint64_t high_chaos = (chaos >> 32);
     349                        uint64_t  mid_chaos = (chaos >> 16) & 0xffff;
     350                        uint64_t  low_chaos = chaos & 0xffff;
     351
     352                        unsigned me = map.self;
     353                        unsigned cpu_chaos = map.start + (mid_chaos % map.count);
     354                        bool global = cpu_chaos == me;
     355
     356                        if(global) {
     357                                proc->rdq.target = high_chaos % lanes.count;
     358                        } else {
     359                                proc->rdq.target = (cpu_chaos * READYQ_SHARD_FACTOR) + (low_chaos % READYQ_SHARD_FACTOR);
     360                                /* paranoid */ verify(proc->rdq.target >= (map.start * READYQ_SHARD_FACTOR));
     361                                /* paranoid */ verify(proc->rdq.target <  ((map.start + map.count) * READYQ_SHARD_FACTOR));
     362                        }
     363
     364                        /* paranoid */ verify(proc->rdq.target != -1u);
     365                }
     366                else {
     367                        const unsigned long long bias = 0; //2_500_000_000;
     368                        const unsigned long long cutoff = proc->rdq.cutoff > bias ? proc->rdq.cutoff - bias : proc->rdq.cutoff;
     369                        {
     370                                unsigned target = proc->rdq.target;
     371                                proc->rdq.target = -1u;
     372                                if(lanes.tscs[target].tv < cutoff && ts(lanes.data[target]) < cutoff) {
     373                                        $thread * t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help));
     374                                        proc->rdq.last = target;
     375                                        if(t) return t;
     376                                }
     377                        }
     378
     379                        unsigned last = proc->rdq.last;
     380                        if(last != -1u && lanes.tscs[last].tv < cutoff && ts(lanes.data[last]) < cutoff) {
     381                                $thread * t = try_pop(cltr, last __STATS(, __tls_stats()->ready.pop.help));
     382                                if(t) return t;
     383                        }
     384                        else {
     385                                proc->rdq.last = -1u;
     386                        }
     387                }
     388
     389                for(READYQ_SHARD_FACTOR) {
     390                        unsigned i = start + (proc->rdq.itr++ % READYQ_SHARD_FACTOR);
     391                        if($thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t;
     392                }
     393
     394                // All lanes where empty return 0p
     395                return 0p;
     396        }
     397
     398        __attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr) with (cltr->ready_queue) {
     399                processor * const proc = kernelTLS().this_processor;
     400                unsigned last = proc->rdq.last;
     401                if(last != -1u) {
     402                        struct $thread * t = try_pop(cltr, last __STATS(, __tls_stats()->ready.pop.steal));
     403                        if(t) return t;
     404                        proc->rdq.last = -1u;
     405                }
     406
     407                unsigned i = __tls_rand() % lanes.count;
     408                return try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal));
     409        }
     410        __attribute__((hot)) struct $thread * pop_search(struct cluster * cltr) {
     411                return search(cltr);
     412        }
     413#endif
    228414#if defined(USE_RELAXED_FIFO)
    229415        //-----------------------------------------------------------------------
     
    519705                                        if(is_empty(sl)) {
    520706                                                assert( sl.anchor.next == 0p );
    521                                                 assert( sl.anchor.ts   == 0 );
     707                                                assert( sl.anchor.ts   == -1llu );
    522708                                                assert( mock_head(sl)  == sl.prev );
    523709                                        } else {
    524710                                                assert( sl.anchor.next != 0p );
    525                                                 assert( sl.anchor.ts   != 0 );
     711                                                assert( sl.anchor.ts   != -1llu );
    526712                                                assert( mock_head(sl)  != sl.prev );
    527713                                        }
     
    573759                lanes.tscs = alloc(lanes.count, lanes.tscs`realloc);
    574760                for(i; lanes.count) {
    575                         unsigned long long tsc = ts(lanes.data[i]);
    576                         lanes.tscs[i].tv = tsc != 0 ? tsc : rdtscl();
     761                        unsigned long long tsc1 = ts(lanes.data[i]);
     762                        unsigned long long tsc2 = rdtscl();
     763                        lanes.tscs[i].tv = min(tsc1, tsc2);
    577764                }
    578765        #endif
    579766}
    580767
    581 // Grow the ready queue
    582 void ready_queue_grow(struct cluster * cltr) {
    583         size_t ncount;
    584         int target = cltr->procs.total;
    585 
    586         /* paranoid */ verify( ready_mutate_islocked() );
    587         __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue\n");
    588 
    589         // Make sure that everything is consistent
    590         /* paranoid */ check( cltr->ready_queue );
    591 
    592         // grow the ready queue
    593         with( cltr->ready_queue ) {
    594                 // Find new count
    595                 // Make sure we always have atleast 1 list
    596                 if(target >= 2) {
    597                         ncount = target * READYQ_SHARD_FACTOR;
    598                 } else {
    599                         ncount = SEQUENTIAL_SHARD;
    600                 }
    601 
    602                 // Allocate new array (uses realloc and memcpies the data)
    603                 lanes.data = alloc( ncount, lanes.data`realloc );
    604 
    605                 // Fix the moved data
    606                 for( idx; (size_t)lanes.count ) {
    607                         fix(lanes.data[idx]);
    608                 }
    609 
    610                 // Construct new data
    611                 for( idx; (size_t)lanes.count ~ ncount) {
    612                         (lanes.data[idx]){};
    613                 }
    614 
    615                 // Update original
    616                 lanes.count = ncount;
    617         }
    618 
    619         fix_times(cltr);
    620 
    621         reassign_cltr_id(cltr);
    622 
    623         // Make sure that everything is consistent
    624         /* paranoid */ check( cltr->ready_queue );
    625 
    626         __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue done\n");
    627 
    628         /* paranoid */ verify( ready_mutate_islocked() );
    629 }
    630 
    631 // Shrink the ready queue
    632 void ready_queue_shrink(struct cluster * cltr) {
    633         /* paranoid */ verify( ready_mutate_islocked() );
    634         __cfadbg_print_safe(ready_queue, "Kernel : Shrinking ready queue\n");
    635 
    636         // Make sure that everything is consistent
    637         /* paranoid */ check( cltr->ready_queue );
    638 
    639         int target = cltr->procs.total;
    640 
    641         with( cltr->ready_queue ) {
    642                 // Remember old count
    643                 size_t ocount = lanes.count;
    644 
    645                 // Find new count
    646                 // Make sure we always have atleast 1 list
    647                 lanes.count = target >= 2 ? target * READYQ_SHARD_FACTOR: SEQUENTIAL_SHARD;
    648                 /* paranoid */ verify( ocount >= lanes.count );
    649                 /* paranoid */ verify( lanes.count == target * READYQ_SHARD_FACTOR || target < 2 );
    650 
    651                 // for printing count the number of displaced threads
    652                 #if defined(__CFA_DEBUG_PRINT__) || defined(__CFA_DEBUG_PRINT_READY_QUEUE__)
    653                         __attribute__((unused)) size_t displaced = 0;
    654                 #endif
    655 
    656                 // redistribute old data
    657                 for( idx; (size_t)lanes.count ~ ocount) {
    658                         // Lock is not strictly needed but makes checking invariants much easier
    659                         __attribute__((unused)) bool locked = __atomic_try_acquire(&lanes.data[idx].lock);
    660                         verify(locked);
    661 
    662                         // As long as we can pop from this lane to push the threads somewhere else in the queue
    663                         while(!is_empty(lanes.data[idx])) {
    664                                 struct $thread * thrd;
    665                                 unsigned long long _;
    666                                 [thrd, _] = pop(lanes.data[idx]);
    667 
    668                                 push(cltr, thrd, true);
    669 
    670                                 // for printing count the number of displaced threads
    671                                 #if defined(__CFA_DEBUG_PRINT__) || defined(__CFA_DEBUG_PRINT_READY_QUEUE__)
    672                                         displaced++;
    673                                 #endif
    674                         }
    675 
    676                         // Unlock the lane
    677                         __atomic_unlock(&lanes.data[idx].lock);
    678 
    679                         // TODO print the queue statistics here
    680 
    681                         ^(lanes.data[idx]){};
    682                 }
    683 
    684                 __cfadbg_print_safe(ready_queue, "Kernel : Shrinking ready queue displaced %zu threads\n", displaced);
    685 
    686                 // Allocate new array (uses realloc and memcpies the data)
    687                 lanes.data = alloc( lanes.count, lanes.data`realloc );
    688 
    689                 // Fix the moved data
    690                 for( idx; (size_t)lanes.count ) {
    691                         fix(lanes.data[idx]);
    692                 }
    693         }
    694 
    695         fix_times(cltr);
    696 
    697         reassign_cltr_id(cltr);
    698 
    699         // Make sure that everything is consistent
    700         /* paranoid */ check( cltr->ready_queue );
    701 
    702         __cfadbg_print_safe(ready_queue, "Kernel : Shrinking ready queue done\n");
    703         /* paranoid */ verify( ready_mutate_islocked() );
    704 }
     768#if defined(USE_CPU_WORK_STEALING)
     769        // ready_queue size is fixed in this case
     770        void ready_queue_grow(struct cluster * cltr) {}
     771        void ready_queue_shrink(struct cluster * cltr) {}
     772#else
     773        // Grow the ready queue
     774        void ready_queue_grow(struct cluster * cltr) {
     775                size_t ncount;
     776                int target = cltr->procs.total;
     777
     778                /* paranoid */ verify( ready_mutate_islocked() );
     779                __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue\n");
     780
     781                // Make sure that everything is consistent
     782                /* paranoid */ check( cltr->ready_queue );
     783
     784                // grow the ready queue
     785                with( cltr->ready_queue ) {
     786                        // Find new count
     787                        // Make sure we always have atleast 1 list
     788                        if(target >= 2) {
     789                                ncount = target * READYQ_SHARD_FACTOR;
     790                        } else {
     791                                ncount = SEQUENTIAL_SHARD;
     792                        }
     793
     794                        // Allocate new array (uses realloc and memcpies the data)
     795                        lanes.data = alloc( ncount, lanes.data`realloc );
     796
     797                        // Fix the moved data
     798                        for( idx; (size_t)lanes.count ) {
     799                                fix(lanes.data[idx]);
     800                        }
     801
     802                        // Construct new data
     803                        for( idx; (size_t)lanes.count ~ ncount) {
     804                                (lanes.data[idx]){};
     805                        }
     806
     807                        // Update original
     808                        lanes.count = ncount;
     809                }
     810
     811                fix_times(cltr);
     812
     813                reassign_cltr_id(cltr);
     814
     815                // Make sure that everything is consistent
     816                /* paranoid */ check( cltr->ready_queue );
     817
     818                __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue done\n");
     819
     820                /* paranoid */ verify( ready_mutate_islocked() );
     821        }
     822
     823        // Shrink the ready queue
     824        void ready_queue_shrink(struct cluster * cltr) {
     825                /* paranoid */ verify( ready_mutate_islocked() );
     826                __cfadbg_print_safe(ready_queue, "Kernel : Shrinking ready queue\n");
     827
     828                // Make sure that everything is consistent
     829                /* paranoid */ check( cltr->ready_queue );
     830
     831                int target = cltr->procs.total;
     832
     833                with( cltr->ready_queue ) {
     834                        // Remember old count
     835                        size_t ocount = lanes.count;
     836
     837                        // Find new count
     838                        // Make sure we always have atleast 1 list
     839                        lanes.count = target >= 2 ? target * READYQ_SHARD_FACTOR: SEQUENTIAL_SHARD;
     840                        /* paranoid */ verify( ocount >= lanes.count );
     841                        /* paranoid */ verify( lanes.count == target * READYQ_SHARD_FACTOR || target < 2 );
     842
     843                        // for printing count the number of displaced threads
     844                        #if defined(__CFA_DEBUG_PRINT__) || defined(__CFA_DEBUG_PRINT_READY_QUEUE__)
     845                                __attribute__((unused)) size_t displaced = 0;
     846                        #endif
     847
     848                        // redistribute old data
     849                        for( idx; (size_t)lanes.count ~ ocount) {
     850                                // Lock is not strictly needed but makes checking invariants much easier
     851                                __attribute__((unused)) bool locked = __atomic_try_acquire(&lanes.data[idx].lock);
     852                                verify(locked);
     853
     854                                // As long as we can pop from this lane to push the threads somewhere else in the queue
     855                                while(!is_empty(lanes.data[idx])) {
     856                                        struct $thread * thrd;
     857                                        unsigned long long _;
     858                                        [thrd, _] = pop(lanes.data[idx]);
     859
     860                                        push(cltr, thrd, true);
     861
     862                                        // for printing count the number of displaced threads
     863                                        #if defined(__CFA_DEBUG_PRINT__) || defined(__CFA_DEBUG_PRINT_READY_QUEUE__)
     864                                                displaced++;
     865                                        #endif
     866                                }
     867
     868                                // Unlock the lane
     869                                __atomic_unlock(&lanes.data[idx].lock);
     870
     871                                // TODO print the queue statistics here
     872
     873                                ^(lanes.data[idx]){};
     874                        }
     875
     876                        __cfadbg_print_safe(ready_queue, "Kernel : Shrinking ready queue displaced %zu threads\n", displaced);
     877
     878                        // Allocate new array (uses realloc and memcpies the data)
     879                        lanes.data = alloc( lanes.count, lanes.data`realloc );
     880
     881                        // Fix the moved data
     882                        for( idx; (size_t)lanes.count ) {
     883                                fix(lanes.data[idx]);
     884                        }
     885                }
     886
     887                fix_times(cltr);
     888
     889                reassign_cltr_id(cltr);
     890
     891                // Make sure that everything is consistent
     892                /* paranoid */ check( cltr->ready_queue );
     893
     894                __cfadbg_print_safe(ready_queue, "Kernel : Shrinking ready queue done\n");
     895                /* paranoid */ verify( ready_mutate_islocked() );
     896        }
     897#endif
    705898
    706899#if !defined(__CFA_NO_STATISTICS__)
     
    710903        }
    711904#endif
     905
     906
     907#if   defined(CFA_HAVE_LINUX_LIBRSEQ)
     908        // No definition needed
     909#elif defined(CFA_HAVE_LINUX_RSEQ_H)
     910
     911        #if defined( __x86_64 ) || defined( __i386 )
     912                #define RSEQ_SIG        0x53053053
     913        #elif defined( __ARM_ARCH )
     914                #ifdef __ARMEB__
     915                #define RSEQ_SIG    0xf3def5e7      /* udf    #24035    ; 0x5de3 (ARMv6+) */
     916                #else
     917                #define RSEQ_SIG    0xe7f5def3      /* udf    #24035    ; 0x5de3 */
     918                #endif
     919        #endif
     920
     921        extern void __disable_interrupts_hard();
     922        extern void __enable_interrupts_hard();
     923
     924        void __kernel_raw_rseq_register  (void) {
     925                /* paranoid */ verify( __cfaabi_rseq.cpu_id == RSEQ_CPU_ID_UNINITIALIZED );
     926
     927                // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, (sigset_t *)0p, _NSIG / 8);
     928                int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, RSEQ_SIG);
     929                if(ret != 0) {
     930                        int e = errno;
     931                        switch(e) {
     932                        case EINVAL: abort("KERNEL ERROR: rseq register invalid argument");
     933                        case ENOSYS: abort("KERNEL ERROR: rseq register no supported");
     934                        case EFAULT: abort("KERNEL ERROR: rseq register with invalid argument");
     935                        case EBUSY : abort("KERNEL ERROR: rseq register already registered");
     936                        case EPERM : abort("KERNEL ERROR: rseq register sig  argument  on unregistration does not match the signature received on registration");
     937                        default: abort("KERNEL ERROR: rseq register unexpected return %d", e);
     938                        }
     939                }
     940        }
     941
     942        void __kernel_raw_rseq_unregister(void) {
     943                /* paranoid */ verify( __cfaabi_rseq.cpu_id >= 0 );
     944
     945                // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, (sigset_t *)0p, _NSIG / 8);
     946                int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
     947                if(ret != 0) {
     948                        int e = errno;
     949                        switch(e) {
     950                        case EINVAL: abort("KERNEL ERROR: rseq unregister invalid argument");
     951                        case ENOSYS: abort("KERNEL ERROR: rseq unregister no supported");
     952                        case EFAULT: abort("KERNEL ERROR: rseq unregister with invalid argument");
     953                        case EBUSY : abort("KERNEL ERROR: rseq unregister already registered");
     954                        case EPERM : abort("KERNEL ERROR: rseq unregister sig  argument  on unregistration does not match the signature received on registration");
     955                        default: abort("KERNEL ERROR: rseq unregisteunexpected return %d", e);
     956                        }
     957                }
     958        }
     959#else
     960        // No definition needed
     961#endif
Note: See TracChangeset for help on using the changeset viewer.