Ignore:
File:
1 edited

Legend:

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

    r00acd66 rcd769305  
    3737#define LIBC_arm32_ATOMIC_H_
    3838
     39#define LIBC_ARCH_ATOMIC_H_
     40#define CAS
     41
     42#include <atomicdflt.h>
     43#include <bool.h>
     44#include <sys/types.h>
     45
     46extern uintptr_t *ras_page;
     47
     48static inline bool cas(atomic_t *val, long ov, long nv)
     49{
     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;
     83}
     84
    3985/** Atomic addition.
    4086 *
     
    4692static inline long atomic_add(atomic_t *val, int i)
    4793{
    48         int ret;
    49         volatile long * mem = &(val->count);
     94        long ret = 0;
    5095
     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         */
    51101        asm volatile (
    52         "1:\n"
    53                 "ldr r2, [%1]\n"
    54                 "add r3, r2, %2\n"
    55                 "str r3, %0\n"
    56                 "swp r3, r3, [%1]\n"
    57                 "cmp r3, r2\n"
    58                 "bne 1b\n"
     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)
     116        );
    59117
    60                 : "=m" (ret)
    61                 : "r" (mem), "r" (i)
    62                 : "r3", "r2"
    63         );
     118        ras_page[0] = 0;
     119        asm volatile ("" ::: "memory");
     120        ras_page[1] = 0xffffffff;
    64121
    65122        return ret;
Note: See TracChangeset for help on using the changeset viewer.