Ignore:
Timestamp:
2011-03-21T22:00:17Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
143932e3
Parents:
b50b5af2 (diff), 7308e84 (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 mainline changes (needs fixes).

File:
1 moved

Legend:

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

    rb50b5af2 r04803bf  
    2727 */
    2828
    29 /** @addtogroup libcarm32       
     29/** @addtogroup libcarm32
    3030 * @{
    3131 */
     
    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, atomic_count_t ov, atomic_count_t nv)
     49{
     50        atomic_count_t 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 (
     80                "" ::: "memory"
     81        );
     82        ras_page[1] = 0xffffffff;
     83       
     84        return (bool) ret;
     85}
     86
    3987/** Atomic addition.
    4088 *
     
    4391 *
    4492 * @return Value after addition.
    45  */
    46 static inline long atomic_add(atomic_t *val, int i)
    47 {
    48         int ret;
    49         volatile long * mem = &(val->count);
    50 
    51         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"
    59 
    60                 : "=m" (ret)
    61                 : "r" (mem), "r" (i)
    62                 : "r3", "r2"
    63         );
    64 
     93 *
     94 */
     95static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
     96{
     97        atomic_count_t ret = 0;
     98       
     99        /*
     100         * The following instructions between labels 1 and 2 constitute a
     101         * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
     102         * the kernel will restart it.
     103         */
     104        asm volatile (
     105                "1:\n"
     106                "       adr %[ret], 1b\n"
     107                "       str %[ret], %[rp0]\n"
     108                "       adr %[ret], 2f\n"
     109                "       str %[ret], %[rp1]\n"
     110                "       ldr %[ret], %[addr]\n"
     111                "       add %[ret], %[ret], %[imm]\n"
     112                "       str %[ret], %[addr]\n"
     113                "2:\n"
     114                : [ret] "+&r" (ret),
     115                  [rp0] "=m" (ras_page[0]),
     116                  [rp1] "=m" (ras_page[1]),
     117                  [addr] "+m" (val->count)
     118                : [imm] "r" (i)
     119        );
     120       
     121        ras_page[0] = 0;
     122        asm volatile (
     123                "" ::: "memory"
     124        );
     125        ras_page[1] = 0xffffffff;
     126       
    65127        return ret;
    66128}
     
    70132 *
    71133 * @param val Variable to be incremented.
     134 *
    72135 */
    73136static inline void atomic_inc(atomic_t *val)
     
    80143 *
    81144 * @param val Variable to be decremented.
     145 *
    82146 */
    83147static inline void atomic_dec(atomic_t *val)
     
    91155 * @param val Variable to be incremented.
    92156 * @return    Value after incrementation.
    93  */
    94 static inline long atomic_preinc(atomic_t *val)
     157 *
     158 */
     159static inline atomic_count_t atomic_preinc(atomic_t *val)
    95160{
    96161        return atomic_add(val, 1);
     
    102167 * @param val Variable to be decremented.
    103168 * @return    Value after decrementation.
    104  */
    105 static inline long atomic_predec(atomic_t *val)
     169 *
     170 */
     171static inline atomic_count_t atomic_predec(atomic_t *val)
    106172{
    107173        return atomic_add(val, -1);
     
    113179 * @param val Variable to be incremented.
    114180 * @return    Value before incrementation.
    115  */
    116 static inline long atomic_postinc(atomic_t *val)
     181 *
     182 */
     183static inline atomic_count_t atomic_postinc(atomic_t *val)
    117184{
    118185        return atomic_add(val, 1) - 1;
     
    124191 * @param val Variable to be decremented.
    125192 * @return    Value before decrementation.
    126  */
    127 static inline long atomic_postdec(atomic_t *val)
     193 *
     194 */
     195static inline atomic_count_t atomic_postdec(atomic_t *val)
    128196{
    129197        return atomic_add(val, -1) + 1;
Note: See TracChangeset for help on using the changeset viewer.