Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/arm32/src/atomic.c

    r25fdb2d r133461c  
    3737
    3838volatile unsigned *ras_page;
    39 
    40 unsigned long long __atomic_load_8(const volatile void *mem0, int model)
    41 {
    42         const volatile unsigned *mem = mem0;
    43 
    44         (void) model;
    45 
    46         union {
    47                 unsigned long long a;
    48                 unsigned b[2];
    49         } ret;
    50 
    51         /*
    52          * The following instructions between labels 1 and 2 constitute a
    53          * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
    54          * the kernel will restart it.
    55          */
    56         asm volatile (
    57             "1:\n"
    58             "   adr %[ret0], 1b\n"
    59             "   str %[ret0], %[rp0]\n"
    60             "   adr %[ret0], 2f\n"
    61             "   str %[ret0], %[rp1]\n"
    62 
    63             "   ldr %[ret0], %[addr0]\n"
    64             "   ldr %[ret1], %[addr1]\n"
    65             "2:\n"
    66             : [ret0] "=&r" (ret.b[0]),
    67               [ret1] "=&r" (ret.b[1]),
    68               [rp0] "=m" (ras_page[0]),
    69               [rp1] "=m" (ras_page[1])
    70             : [addr0] "m" (mem[0]),
    71               [addr1] "m" (mem[1])
    72         );
    73 
    74         ras_page[0] = 0;
    75         ras_page[1] = 0xffffffff;
    76 
    77         return ret.a;
    78 }
    79 
    80 void __atomic_store_8(volatile void *mem0, unsigned long long val, int model)
    81 {
    82         volatile unsigned *mem = mem0;
    83 
    84         (void) model;
    85 
    86         union {
    87                 unsigned long long a;
    88                 unsigned b[2];
    89         } v;
    90 
    91         v.a = val;
    92 
    93         /* scratch register */
    94         unsigned tmp;
    95 
    96         /*
    97          * The following instructions between labels 1 and 2 constitute a
    98          * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
    99          * the kernel will restart it.
    100          */
    101         asm volatile (
    102             "1:\n"
    103             "   adr %[tmp], 1b\n"
    104             "   str %[tmp], %[rp0]\n"
    105             "   adr %[tmp], 2f\n"
    106             "   str %[tmp], %[rp1]\n"
    107 
    108             "   str %[val0], %[addr0]\n"
    109             "   str %[val1], %[addr1]\n"
    110             "2:\n"
    111             : [tmp] "=&r" (tmp),
    112               [rp0] "=m" (ras_page[0]),
    113               [rp1] "=m" (ras_page[1]),
    114               [addr0] "=m" (mem[0]),
    115               [addr1] "=m" (mem[1])
    116             : [val0] "r" (v.b[0]),
    117               [val1] "r" (v.b[1])
    118         );
    119 
    120         ras_page[0] = 0;
    121         ras_page[1] = 0xffffffff;
    122 }
    123 
    124 bool __atomic_compare_exchange_1(volatile void *mem0, void *expected0,
    125     unsigned char desired, bool weak, int success, int failure)
    126 {
    127         volatile unsigned char *mem = mem0;
    128         unsigned char *expected = expected0;
    129 
    130         (void) success;
    131         (void) failure;
    132         (void) weak;
    133 
    134         unsigned char ov = *expected;
    135         unsigned ret;
    136 
    137         /*
    138          * The following instructions between labels 1 and 2 constitute a
    139          * Restartable Atomic Sequence. Should the sequence be non-atomic,
    140          * the kernel will restart it.
    141          */
    142         asm volatile (
    143             "1:\n"
    144             "   adr %[ret], 1b\n"
    145             "   str %[ret], %[rp0]\n"
    146             "   adr %[ret], 2f\n"
    147             "   str %[ret], %[rp1]\n"
    148 
    149             "   ldrb %[ret], %[addr]\n"
    150             "   cmp %[ret], %[ov]\n"
    151             "   streqb %[nv], %[addr]\n"
    152             "2:\n"
    153             : [ret] "=&r" (ret),
    154               [rp0] "=m" (ras_page[0]),
    155               [rp1] "=m" (ras_page[1]),
    156               [addr] "+m" (*mem)
    157             : [ov] "r" (ov),
    158               [nv] "r" (desired)
    159         );
    160 
    161         ras_page[0] = 0;
    162         ras_page[1] = 0xffffffff;
    163 
    164         if (ret == ov)
    165                 return true;
    166 
    167         *expected = ret;
    168         return false;
    169 }
    17039
    17140bool __atomic_compare_exchange_4(volatile void *mem0, void *expected0,
     
    21584        *expected = ret;
    21685        return false;
    217 }
    218 
    219 unsigned char __atomic_exchange_1(volatile void *mem0, unsigned char val,
    220     int model)
    221 {
    222         volatile unsigned char *mem = mem0;
    223 
    224         (void) model;
    225 
    226         unsigned ret;
    227 
    228         /*
    229          * The following instructions between labels 1 and 2 constitute a
    230          * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
    231          * the kernel will restart it.
    232          */
    233         asm volatile (
    234             "1:\n"
    235             "   adr %[ret], 1b\n"
    236             "   str %[ret], %[rp0]\n"
    237             "   adr %[ret], 2f\n"
    238             "   str %[ret], %[rp1]\n"
    239             "   ldrb %[ret], %[addr]\n"
    240             "   strb %[imm], %[addr]\n"
    241             "2:\n"
    242             : [ret] "=&r" (ret),
    243               [rp0] "=m" (ras_page[0]),
    244               [rp1] "=m" (ras_page[1]),
    245               [addr] "+m" (*mem)
    246             : [imm] "r" (val)
    247         );
    248 
    249         ras_page[0] = 0;
    250         ras_page[1] = 0xffffffff;
    251 
    252         return ret;
    253 }
    254 
    255 unsigned short __atomic_exchange_2(volatile void *mem0, unsigned short val,
    256     int model)
    257 {
    258         volatile unsigned short *mem = mem0;
    259 
    260         (void) model;
    261 
    262         unsigned ret;
    263 
    264         /*
    265          * The following instructions between labels 1 and 2 constitute a
    266          * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
    267          * the kernel will restart it.
    268          */
    269         asm volatile (
    270             "1:\n"
    271             "   adr %[ret], 1b\n"
    272             "   str %[ret], %[rp0]\n"
    273             "   adr %[ret], 2f\n"
    274             "   str %[ret], %[rp1]\n"
    275             "   ldrh %[ret], %[addr]\n"
    276             "   strh %[imm], %[addr]\n"
    277             "2:\n"
    278             : [ret] "=&r" (ret),
    279               [rp0] "=m" (ras_page[0]),
    280               [rp1] "=m" (ras_page[1]),
    281               [addr] "+m" (*mem)
    282             : [imm] "r" (val)
    283         );
    284 
    285         ras_page[0] = 0;
    286         ras_page[1] = 0xffffffff;
    287 
    288         return ret;
    289 }
    290 
    291 unsigned __atomic_exchange_4(volatile void *mem0, unsigned val, int model)
    292 {
    293         volatile unsigned *mem = mem0;
    294 
    295         (void) model;
    296 
    297         unsigned ret;
    298 
    299         /*
    300          * The following instructions between labels 1 and 2 constitute a
    301          * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
    302          * the kernel will restart it.
    303          */
    304         asm volatile (
    305             "1:\n"
    306             "   adr %[ret], 1b\n"
    307             "   str %[ret], %[rp0]\n"
    308             "   adr %[ret], 2f\n"
    309             "   str %[ret], %[rp1]\n"
    310             "   ldr %[ret], %[addr]\n"
    311             "   str %[imm], %[addr]\n"
    312             "2:\n"
    313             : [ret] "=&r" (ret),
    314               [rp0] "=m" (ras_page[0]),
    315               [rp1] "=m" (ras_page[1]),
    316               [addr] "+m" (*mem)
    317             : [imm] "r" (val)
    318         );
    319 
    320         ras_page[0] = 0;
    321         ras_page[1] = 0xffffffff;
    322 
    323         return ret;
    32486}
    32587
     
    402164}
    403165
    404 bool __atomic_test_and_set(volatile void *ptr, int memorder)
    405 {
    406         volatile unsigned char *b = ptr;
    407 
    408         unsigned char orig = __atomic_exchange_n(b, (unsigned char) true, memorder);
    409         return orig != 0;
    410 }
    411 
    412166void __sync_synchronize(void)
    413167{
Note: See TracChangeset for help on using the changeset viewer.