Changeset ffa73c6 in mainline


Ignore:
Timestamp:
2018-09-06T18:49:14Z (5 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4621d23
Parents:
7328ff4
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-08-13 02:26:04)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-09-06 18:49:14)
Message:

Use compiler builtins for uspace atomics

Location:
uspace/lib/c
Files:
10 deleted
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r7328ff4 rffa73c6  
    129129        generic/stdio/sstream.c \
    130130        generic/stdio/vsprintf.c \
    131         generic/thread/atomic.c \
    132131        generic/thread/fibril.c \
    133132        generic/thread/fibril_synch.c \
  • uspace/lib/c/arch/arm32/Makefile.inc

    r7328ff4 rffa73c6  
    2929
    3030ARCH_SOURCES = \
     31        arch/$(UARCH)/src/atomic.c \
    3132        arch/$(UARCH)/src/entryjmp.S \
    3233        arch/$(UARCH)/src/thread_entry.S \
  • uspace/lib/c/arch/arm32/src/atomic.c

    r7328ff4 rffa73c6  
    11/*
    22 * Copyright (c) 2007 Michal Kebrt
     3 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    34 * All rights reserved.
    45 *
     
    2728 */
    2829
    29 /** @addtogroup libcarm32
    30  * @{
    31  */
    32 /** @file
    33  *  @brief Atomic operations.
     30/*
     31 * Older ARMs don't have atomic instructions, so we need to define a bunch
     32 * of symbols for GCC to use.
    3433 */
    3534
    36 #ifndef LIBC_arm32_ATOMIC_H_
    37 #define LIBC_arm32_ATOMIC_H_
     35#include <stdbool.h>
    3836
    39 #define LIBC_ARCH_ATOMIC_H_
    40 #define CAS
     37extern volatile unsigned *ras_page;
    4138
    42 #include <atomicdflt.h>
    43 #include <stdbool.h>
    44 #include <stdint.h>
     39bool __atomic_compare_exchange_4(volatile unsigned *mem, unsigned *expected, unsigned desired, bool weak, int success, int failure)
     40{
     41        (void) success;
     42        (void) failure;
     43        (void) weak;
    4544
    46 extern uintptr_t *ras_page;
    47 
    48 static inline bool cas(atomic_t *val, atomic_count_t ov, atomic_count_t nv)
    49 {
    50         atomic_count_t ret = 0;
     45        unsigned ov = *expected;
     46        unsigned ret;
    5147
    5248        /*
     
    6157            "   adr %[ret], 2f\n"
    6258            "   str %[ret], %[rp1]\n"
     59
    6360            "   ldr %[ret], %[addr]\n"
    6461            "   cmp %[ret], %[ov]\n"
    6562            "   streq %[nv], %[addr]\n"
    6663            "2:\n"
    67             "   moveq %[ret], #1\n"
    68             "   movne %[ret], #0\n"
    69             : [ret] "+&r" (ret),
     64            : [ret] "=&r" (ret),
    7065              [rp0] "=m" (ras_page[0]),
    7166              [rp1] "=m" (ras_page[1]),
    72               [addr] "+m" (val->count)
     67              [addr] "+m" (*mem)
    7368            : [ov] "r" (ov),
    74               [nv] "r" (nv)
     69              [nv] "r" (desired)
    7570            : "memory"
    7671        );
    7772
    7873        ras_page[0] = 0;
    79         asm volatile (
    80             "" ::: "memory"
    81         );
    8274        ras_page[1] = 0xffffffff;
    8375
    84         return ret != 0;
     76        if (ret == ov)
     77                return true;
     78
     79        *expected = ret;
     80        return false;
    8581}
    8682
    87 /** Atomic addition.
    88  *
    89  * @param val Where to add.
    90  * @param i   Value to be added.
    91  *
    92  * @return Value after addition.
    93  *
    94  */
    95 static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
     83unsigned __atomic_fetch_add_4(volatile unsigned *mem, unsigned val, int model)
    9684{
    97         atomic_count_t ret = 0;
     85        (void) model;
     86
     87        unsigned ret;
    9888
    9989        /*
     
    112102            "   str %[ret], %[addr]\n"
    113103            "2:\n"
    114             : [ret] "+&r" (ret),
     104            : [ret] "=&r" (ret),
    115105              [rp0] "=m" (ras_page[0]),
    116106              [rp1] "=m" (ras_page[1]),
    117               [addr] "+m" (val->count)
    118             : [imm] "r" (i)
     107              [addr] "+m" (*mem)
     108            : [imm] "r" (val)
    119109        );
    120110
    121111        ras_page[0] = 0;
    122         asm volatile (
    123             "" ::: "memory"
    124         );
    125112        ras_page[1] = 0xffffffff;
    126113
    127         return ret;
     114        return ret - val;
    128115}
    129116
    130 
    131 /** Atomic increment.
    132  *
    133  * @param val Variable to be incremented.
    134  *
    135  */
    136 static inline void atomic_inc(atomic_t *val)
     117unsigned __atomic_fetch_sub_4(volatile unsigned *mem, unsigned val, int model)
    137118{
    138         atomic_add(val, 1);
     119        return __atomic_fetch_add_4(mem, -val, model);
    139120}
    140121
    141 
    142 /** Atomic decrement.
    143  *
    144  * @param val Variable to be decremented.
    145  *
    146  */
    147 static inline void atomic_dec(atomic_t *val)
     122void __sync_synchronize(void)
    148123{
    149         atomic_add(val, -1);
     124        // FIXME: Full memory barrier. We might need a syscall for this.
    150125}
    151126
    152 
    153 /** Atomic pre-increment.
    154  *
    155  * @param val Variable to be incremented.
    156  * @return    Value after incrementation.
    157  *
    158  */
    159 static inline atomic_count_t atomic_preinc(atomic_t *val)
     127unsigned __sync_add_and_fetch_4(volatile void *vptr, unsigned val)
    160128{
    161         return atomic_add(val, 1);
     129        return __atomic_fetch_add_4(vptr, val, __ATOMIC_SEQ_CST) + val;
    162130}
    163131
    164 
    165 /** Atomic pre-decrement.
    166  *
    167  * @param val Variable to be decremented.
    168  * @return    Value after decrementation.
    169  *
    170  */
    171 static inline atomic_count_t atomic_predec(atomic_t *val)
     132unsigned __sync_sub_and_fetch_4(volatile void *vptr, unsigned val)
    172133{
    173         return atomic_add(val, -1);
     134        return __atomic_fetch_sub_4(vptr, val, __ATOMIC_SEQ_CST) - val;
    174135}
    175136
    176 
    177 /** Atomic post-increment.
    178  *
    179  * @param val Variable to be incremented.
    180  * @return    Value before incrementation.
    181  *
    182  */
    183 static inline atomic_count_t atomic_postinc(atomic_t *val)
     137bool __sync_bool_compare_and_swap_4(volatile void *ptr, unsigned old_val, unsigned new_val)
    184138{
    185         return atomic_add(val, 1) - 1;
     139        return __atomic_compare_exchange_4(ptr, &old_val, new_val, false,
     140            __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
    186141}
    187142
    188 
    189 /** Atomic post-decrement.
    190  *
    191  * @param val Variable to be decremented.
    192  * @return    Value before decrementation.
    193  *
    194  */
    195 static inline atomic_count_t atomic_postdec(atomic_t *val)
     143unsigned __sync_val_compare_and_swap_4(volatile void *ptr, unsigned old_val, unsigned new_val)
    196144{
    197         return atomic_add(val, -1) + 1;
     145        __atomic_compare_exchange_4(ptr, &old_val, new_val, false,
     146            __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
     147        return old_val;
    198148}
    199149
    200 
    201 #endif
    202 
    203 /** @}
    204  */
  • uspace/lib/c/include/atomic.h

    r7328ff4 rffa73c6  
    3636#define LIBC_ATOMIC_H_
    3737
    38 #include <libarch/atomic.h>
     38#include <stdatomic.h>
     39#include <stdbool.h>
     40#include <stddef.h>
     41
     42typedef size_t atomic_count_t;
     43typedef ssize_t atomic_signed_t;
     44
     45typedef struct atomic {
     46        volatile atomic_size_t count;
     47} atomic_t;
     48
     49static inline void atomic_set(atomic_t *val, atomic_count_t i)
     50{
     51        atomic_store(&val->count, i);
     52}
     53
     54static inline atomic_count_t atomic_get(atomic_t *val)
     55{
     56        return atomic_load(&val->count);
     57}
     58
     59static inline bool cas(atomic_t *val, atomic_count_t ov, atomic_count_t nv)
     60{
     61        return atomic_compare_exchange_strong(&val->count, &ov, nv);
     62}
     63
     64static inline atomic_count_t atomic_postinc(atomic_t *val)
     65{
     66        return atomic_fetch_add(&val->count, 1);
     67}
     68
     69static inline atomic_count_t atomic_postdec(atomic_t *val)
     70{
     71        return atomic_fetch_sub(&val->count, 1);
     72}
     73
     74static inline atomic_count_t atomic_preinc(atomic_t *val)
     75{
     76        return atomic_postinc(val) + 1;
     77}
     78
     79static inline atomic_count_t atomic_predec(atomic_t *val)
     80{
     81        return atomic_postdec(val) - 1;
     82}
     83
     84static inline void atomic_inc(atomic_t *val)
     85{
     86        atomic_postinc(val);
     87}
     88
     89static inline void atomic_dec(atomic_t *val)
     90{
     91        atomic_postdec(val);
     92}
    3993
    4094#endif
Note: See TracChangeset for help on using the changeset viewer.