Changeset cd769305 in mainline
- Timestamp:
- 2009-12-07T21:57:22Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 216cb85
- Parents:
- a47d49f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/arch/arm32/include/atomic.h
ra47d49f rcd769305 37 37 #define LIBC_arm32_ATOMIC_H_ 38 38 39 #define LIBC_ARCH_ATOMIC_H_ 40 #define CAS 41 42 #include <atomicdflt.h> 39 43 #include <bool.h> 44 #include <sys/types.h> 40 45 41 typedef struct atomic { 42 volatile long count; 43 } atomic_t; 44 45 static inline void atomic_set(atomic_t *val, long i) 46 { 47 val->count = i; 48 } 49 50 static inline long atomic_get(atomic_t *val) 51 { 52 return val->count; 53 } 46 extern uintptr_t *ras_page; 54 47 55 48 static inline bool cas(atomic_t *val, long ov, long nv) 56 49 { 57 /* FIXME: is not atomic */ 58 if (val->count == ov) { 59 val->count = nv; 60 return true; 61 } 62 return false; 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; 63 83 } 64 84 … … 72 92 static inline long atomic_add(atomic_t *val, int i) 73 93 { 74 int ret; 75 volatile long * mem = &(val->count); 94 long ret = 0; 76 95 77 /* FIXME: is not atomic, is broken */ 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 */ 78 101 asm volatile ( 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" 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 ); 86 117 87 : "=m" (ret) 88 : "r" (mem), "r" (i) 89 : "r3", "r2" 90 ); 118 ras_page[0] = 0; 119 asm volatile ("" ::: "memory"); 120 ras_page[1] = 0xffffffff; 91 121 92 122 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.