Ignore:
File:
1 edited

Legend:

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

    r3ffb69b r25fdb2d  
    3434
    3535#include <stdbool.h>
     36#include "ras_page.h"
    3637
    3738volatile unsigned *ras_page;
    3839
    39 bool __atomic_compare_exchange_4(volatile unsigned *mem, unsigned *expected, unsigned desired, bool weak, int success, int failure)
    40 {
     40unsigned 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
     80void __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
     124bool __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
    41130        (void) success;
    42131        (void) failure;
    43132        (void) weak;
    44133
     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}
     170
     171bool __atomic_compare_exchange_4(volatile void *mem0, void *expected0,
     172    unsigned desired, bool weak, int success, int failure)
     173{
     174        volatile unsigned *mem = mem0;
     175        unsigned *expected = expected0;
     176
     177        (void) success;
     178        (void) failure;
     179        (void) weak;
     180
    45181        unsigned ov = *expected;
    46182        unsigned ret;
     
    81217}
    82218
    83 unsigned short __atomic_fetch_add_2(volatile unsigned short *mem, unsigned short val, int model)
    84 {
     219unsigned 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
     255unsigned 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
     291unsigned __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;
     324}
     325
     326unsigned short __atomic_fetch_add_2(volatile void *mem0, unsigned short val,
     327    int model)
     328{
     329        volatile unsigned short *mem = mem0;
     330
    85331        (void) model;
    86332
     
    115361}
    116362
    117 unsigned __atomic_fetch_add_4(volatile unsigned *mem, unsigned val, int model)
    118 {
     363unsigned __atomic_fetch_add_4(volatile void *mem0, unsigned val, int model)
     364{
     365        volatile unsigned *mem = mem0;
     366
    119367        (void) model;
    120368
     
    149397}
    150398
    151 unsigned __atomic_fetch_sub_4(volatile unsigned *mem, unsigned val, int model)
     399unsigned __atomic_fetch_sub_4(volatile void *mem, unsigned val, int model)
    152400{
    153401        return __atomic_fetch_add_4(mem, -val, model);
     402}
     403
     404bool __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;
    154410}
    155411
Note: See TracChangeset for help on using the changeset viewer.