Changes in uspace/lib/c/arch/arm32/src/atomic.c [3ffb69b:25fdb2d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/arch/arm32/src/atomic.c
r3ffb69b r25fdb2d 34 34 35 35 #include <stdbool.h> 36 #include "ras_page.h" 36 37 37 38 volatile unsigned *ras_page; 38 39 39 bool __atomic_compare_exchange_4(volatile unsigned *mem, unsigned *expected, unsigned desired, bool weak, int success, int failure) 40 { 40 unsigned long long __atomic_load_8(const volatile void *mem0, int model) 41 { 42 const volatile unsigned *mem = mem0; 43 44 (void) model; 45 46 union { 47 unsigned long long a; 48 unsigned b[2]; 49 } ret; 50 51 /* 52 * The following instructions between labels 1 and 2 constitute a 53 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 54 * the kernel will restart it. 55 */ 56 asm volatile ( 57 "1:\n" 58 " adr %[ret0], 1b\n" 59 " str %[ret0], %[rp0]\n" 60 " adr %[ret0], 2f\n" 61 " str %[ret0], %[rp1]\n" 62 63 " ldr %[ret0], %[addr0]\n" 64 " ldr %[ret1], %[addr1]\n" 65 "2:\n" 66 : [ret0] "=&r" (ret.b[0]), 67 [ret1] "=&r" (ret.b[1]), 68 [rp0] "=m" (ras_page[0]), 69 [rp1] "=m" (ras_page[1]) 70 : [addr0] "m" (mem[0]), 71 [addr1] "m" (mem[1]) 72 ); 73 74 ras_page[0] = 0; 75 ras_page[1] = 0xffffffff; 76 77 return ret.a; 78 } 79 80 void __atomic_store_8(volatile void *mem0, unsigned long long val, int model) 81 { 82 volatile unsigned *mem = mem0; 83 84 (void) model; 85 86 union { 87 unsigned long long a; 88 unsigned b[2]; 89 } v; 90 91 v.a = val; 92 93 /* scratch register */ 94 unsigned tmp; 95 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 */ 101 asm volatile ( 102 "1:\n" 103 " adr %[tmp], 1b\n" 104 " str %[tmp], %[rp0]\n" 105 " adr %[tmp], 2f\n" 106 " str %[tmp], %[rp1]\n" 107 108 " str %[val0], %[addr0]\n" 109 " str %[val1], %[addr1]\n" 110 "2:\n" 111 : [tmp] "=&r" (tmp), 112 [rp0] "=m" (ras_page[0]), 113 [rp1] "=m" (ras_page[1]), 114 [addr0] "=m" (mem[0]), 115 [addr1] "=m" (mem[1]) 116 : [val0] "r" (v.b[0]), 117 [val1] "r" (v.b[1]) 118 ); 119 120 ras_page[0] = 0; 121 ras_page[1] = 0xffffffff; 122 } 123 124 bool __atomic_compare_exchange_1(volatile void *mem0, void *expected0, 125 unsigned char desired, bool weak, int success, int failure) 126 { 127 volatile unsigned char *mem = mem0; 128 unsigned char *expected = expected0; 129 41 130 (void) success; 42 131 (void) failure; 43 132 (void) weak; 44 133 134 unsigned char ov = *expected; 135 unsigned ret; 136 137 /* 138 * The following instructions between labels 1 and 2 constitute a 139 * Restartable Atomic Sequence. Should the sequence be non-atomic, 140 * the kernel will restart it. 141 */ 142 asm volatile ( 143 "1:\n" 144 " adr %[ret], 1b\n" 145 " str %[ret], %[rp0]\n" 146 " adr %[ret], 2f\n" 147 " str %[ret], %[rp1]\n" 148 149 " ldrb %[ret], %[addr]\n" 150 " cmp %[ret], %[ov]\n" 151 " streqb %[nv], %[addr]\n" 152 "2:\n" 153 : [ret] "=&r" (ret), 154 [rp0] "=m" (ras_page[0]), 155 [rp1] "=m" (ras_page[1]), 156 [addr] "+m" (*mem) 157 : [ov] "r" (ov), 158 [nv] "r" (desired) 159 ); 160 161 ras_page[0] = 0; 162 ras_page[1] = 0xffffffff; 163 164 if (ret == ov) 165 return true; 166 167 *expected = ret; 168 return false; 169 } 170 171 bool __atomic_compare_exchange_4(volatile void *mem0, void *expected0, 172 unsigned desired, bool weak, int success, int failure) 173 { 174 volatile unsigned *mem = mem0; 175 unsigned *expected = expected0; 176 177 (void) success; 178 (void) failure; 179 (void) weak; 180 45 181 unsigned ov = *expected; 46 182 unsigned ret; … … 81 217 } 82 218 83 unsigned short __atomic_fetch_add_2(volatile unsigned short *mem, unsigned short val, int model) 84 { 219 unsigned char __atomic_exchange_1(volatile void *mem0, unsigned char val, 220 int model) 221 { 222 volatile unsigned char *mem = mem0; 223 224 (void) model; 225 226 unsigned ret; 227 228 /* 229 * The following instructions between labels 1 and 2 constitute a 230 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 231 * the kernel will restart it. 232 */ 233 asm volatile ( 234 "1:\n" 235 " adr %[ret], 1b\n" 236 " str %[ret], %[rp0]\n" 237 " adr %[ret], 2f\n" 238 " str %[ret], %[rp1]\n" 239 " ldrb %[ret], %[addr]\n" 240 " strb %[imm], %[addr]\n" 241 "2:\n" 242 : [ret] "=&r" (ret), 243 [rp0] "=m" (ras_page[0]), 244 [rp1] "=m" (ras_page[1]), 245 [addr] "+m" (*mem) 246 : [imm] "r" (val) 247 ); 248 249 ras_page[0] = 0; 250 ras_page[1] = 0xffffffff; 251 252 return ret; 253 } 254 255 unsigned short __atomic_exchange_2(volatile void *mem0, unsigned short val, 256 int model) 257 { 258 volatile unsigned short *mem = mem0; 259 260 (void) model; 261 262 unsigned ret; 263 264 /* 265 * The following instructions between labels 1 and 2 constitute a 266 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 267 * the kernel will restart it. 268 */ 269 asm volatile ( 270 "1:\n" 271 " adr %[ret], 1b\n" 272 " str %[ret], %[rp0]\n" 273 " adr %[ret], 2f\n" 274 " str %[ret], %[rp1]\n" 275 " ldrh %[ret], %[addr]\n" 276 " strh %[imm], %[addr]\n" 277 "2:\n" 278 : [ret] "=&r" (ret), 279 [rp0] "=m" (ras_page[0]), 280 [rp1] "=m" (ras_page[1]), 281 [addr] "+m" (*mem) 282 : [imm] "r" (val) 283 ); 284 285 ras_page[0] = 0; 286 ras_page[1] = 0xffffffff; 287 288 return ret; 289 } 290 291 unsigned __atomic_exchange_4(volatile void *mem0, unsigned val, int model) 292 { 293 volatile unsigned *mem = mem0; 294 295 (void) model; 296 297 unsigned ret; 298 299 /* 300 * The following instructions between labels 1 and 2 constitute a 301 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 302 * the kernel will restart it. 303 */ 304 asm volatile ( 305 "1:\n" 306 " adr %[ret], 1b\n" 307 " str %[ret], %[rp0]\n" 308 " adr %[ret], 2f\n" 309 " str %[ret], %[rp1]\n" 310 " ldr %[ret], %[addr]\n" 311 " str %[imm], %[addr]\n" 312 "2:\n" 313 : [ret] "=&r" (ret), 314 [rp0] "=m" (ras_page[0]), 315 [rp1] "=m" (ras_page[1]), 316 [addr] "+m" (*mem) 317 : [imm] "r" (val) 318 ); 319 320 ras_page[0] = 0; 321 ras_page[1] = 0xffffffff; 322 323 return ret; 324 } 325 326 unsigned short __atomic_fetch_add_2(volatile void *mem0, unsigned short val, 327 int model) 328 { 329 volatile unsigned short *mem = mem0; 330 85 331 (void) model; 86 332 … … 115 361 } 116 362 117 unsigned __atomic_fetch_add_4(volatile unsigned *mem, unsigned val, int model) 118 { 363 unsigned __atomic_fetch_add_4(volatile void *mem0, unsigned val, int model) 364 { 365 volatile unsigned *mem = mem0; 366 119 367 (void) model; 120 368 … … 149 397 } 150 398 151 unsigned __atomic_fetch_sub_4(volatile unsigned *mem, unsigned val, int model)399 unsigned __atomic_fetch_sub_4(volatile void *mem, unsigned val, int model) 152 400 { 153 401 return __atomic_fetch_add_4(mem, -val, model); 402 } 403 404 bool __atomic_test_and_set(volatile void *ptr, int memorder) 405 { 406 volatile unsigned char *b = ptr; 407 408 unsigned char orig = __atomic_exchange_n(b, (unsigned char) true, memorder); 409 return orig != 0; 154 410 } 155 411
Note:
See TracChangeset
for help on using the changeset viewer.