Changes in uspace/lib/c/arch/arm32/src/atomic.c [25fdb2d:133461c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/arch/arm32/src/atomic.c
r25fdb2d r133461c 37 37 38 38 volatile unsigned *ras_page; 39 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 a53 * 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 a98 * 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 130 (void) success;131 (void) failure;132 (void) weak;133 134 unsigned char ov = *expected;135 unsigned ret;136 137 /*138 * The following instructions between labels 1 and 2 constitute a139 * 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 39 171 40 bool __atomic_compare_exchange_4(volatile void *mem0, void *expected0, … … 215 84 *expected = ret; 216 85 return false; 217 }218 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 a230 * 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 a266 * 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 a301 * 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 86 } 325 87 … … 402 164 } 403 165 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;410 }411 412 166 void __sync_synchronize(void) 413 167 {
Note:
See TracChangeset
for help on using the changeset viewer.