Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/arch/arm32/include/atomic.h

    rcd769305 r8d04f709  
    3737#define LIBC_arm32_ATOMIC_H_
    3838
    39 #define LIBC_ARCH_ATOMIC_H_
    40 #define CAS
     39#include <bool.h>
    4140
    42 #include <atomicdflt.h>
    43 #include <bool.h>
    44 #include <sys/types.h>
     41typedef struct atomic {
     42        volatile long count;
     43} atomic_t;
    4544
    46 extern uintptr_t *ras_page;
     45static inline void atomic_set(atomic_t *val, long i)
     46{
     47        val->count = i;
     48}
     49
     50static inline long atomic_get(atomic_t *val)
     51{
     52        return val->count;
     53}
    4754
    4855static inline bool cas(atomic_t *val, long ov, long nv)
    4956{
    50         long ret = 0;
    51 
    52         /*
    53          * The following instructions between labels 1 and 2 constitute a
    54          * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
    55          * the kernel will restart it.
    56          */
    57         asm volatile (
    58                 "1:\n"
    59                 "       adr %[ret], 1b\n"
    60                 "       str %[ret], %[rp0]\n"
    61                 "       adr %[ret], 2f\n"
    62                 "       str %[ret], %[rp1]\n"
    63                 "       ldr %[ret], %[addr]\n"
    64                 "       cmp %[ret], %[ov]\n"
    65                 "       streq %[nv], %[addr]\n"
    66                 "2:\n"
    67                 "       moveq %[ret], #1\n"
    68                 "       movne %[ret], #0\n"
    69                 : [ret] "+&r" (ret),
    70                   [rp0] "=m" (ras_page[0]),
    71                   [rp1] "=m" (ras_page[1]),
    72                   [addr] "+m" (val->count)
    73                 : [ov] "r" (ov),
    74                   [nv] "r" (nv)
    75                 : "memory"
    76         );
    77 
    78         ras_page[0] = 0;
    79         asm volatile ("" ::: "memory");
    80         ras_page[1] = 0xffffffff;
    81 
    82         return (bool) ret;
     57        /* FIXME: is not atomic */
     58        if (val->count == ov) {
     59                val->count = nv;
     60                return true;
     61        }
     62        return false;
    8363}
    8464
     
    9272static inline long atomic_add(atomic_t *val, int i)
    9373{
    94         long ret = 0;
     74        int ret;
     75        volatile long * mem = &(val->count);
    9576
    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          */
     77        /* FIXME: is not atomic, is broken */
    10178        asm volatile (
    102                 "1:\n"
    103                 "       adr %[ret], 1b\n"
    104                 "       str %[ret], %[rp0]\n"
    105                 "       adr %[ret], 2f\n"
    106                 "       str %[ret], %[rp1]\n"
    107                 "       ldr %[ret], %[addr]\n"
    108                 "       add %[ret], %[ret], %[imm]\n"
    109                 "       str %[ret], %[addr]\n"
    110                 "2:\n"
    111                 : [ret] "+&r" (ret),
    112                   [rp0] "=m" (ras_page[0]),
    113                   [rp1] "=m" (ras_page[1]),
    114                   [addr] "+m" (val->count)
    115                 : [imm] "r" (i)
     79        "1:\n"
     80                "ldr r2, [%1]\n"
     81                "add r3, r2, %2\n"
     82                "str r3, %0\n"
     83                "swp r3, r3, [%1]\n"
     84                "cmp r3, r2\n"
     85                "bne 1b\n"
     86
     87                : "=m" (ret)
     88                : "r" (mem), "r" (i)
     89                : "r3", "r2"
    11690        );
    117 
    118         ras_page[0] = 0;
    119         asm volatile ("" ::: "memory");
    120         ras_page[1] = 0xffffffff;
    12191
    12292        return ret;
Note: See TracChangeset for help on using the changeset viewer.