github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/runtime/atomic_arm.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "runtime.h" 6 #include "arch_GOARCH.h" 7 8 static struct { 9 Lock l; 10 byte pad[CacheLineSize-sizeof(Lock)]; 11 } locktab[57]; 12 13 #define LOCK(addr) (&locktab[((uintptr)(addr)>>3)%nelem(locktab)].l) 14 15 // Atomic add and return new value. 16 #pragma textflag 7 17 uint32 18 runtime·xadd(uint32 volatile *val, int32 delta) 19 { 20 uint32 oval, nval; 21 22 for(;;){ 23 oval = *val; 24 nval = oval + delta; 25 if(runtime·cas(val, oval, nval)) 26 return nval; 27 } 28 } 29 30 #pragma textflag 7 31 uint32 32 runtime·xchg(uint32 volatile* addr, uint32 v) 33 { 34 uint32 old; 35 36 for(;;) { 37 old = *addr; 38 if(runtime·cas(addr, old, v)) 39 return old; 40 } 41 } 42 43 #pragma textflag 7 44 void 45 runtime·procyield(uint32 cnt) 46 { 47 uint32 volatile i; 48 49 for(i = 0; i < cnt; i++) { 50 } 51 } 52 53 #pragma textflag 7 54 uint32 55 runtime·atomicload(uint32 volatile* addr) 56 { 57 return runtime·xadd(addr, 0); 58 } 59 60 #pragma textflag 7 61 void* 62 runtime·atomicloadp(void* volatile* addr) 63 { 64 return (void*)runtime·xadd((uint32 volatile*)addr, 0); 65 } 66 67 #pragma textflag 7 68 void 69 runtime·atomicstorep(void* volatile* addr, void* v) 70 { 71 void *old; 72 73 for(;;) { 74 old = *addr; 75 if(runtime·casp(addr, old, v)) 76 return; 77 } 78 } 79 80 #pragma textflag 7 81 void 82 runtime·atomicstore(uint32 volatile* addr, uint32 v) 83 { 84 uint32 old; 85 86 for(;;) { 87 old = *addr; 88 if(runtime·cas(addr, old, v)) 89 return; 90 } 91 } 92 93 #pragma textflag 7 94 bool 95 runtime·cas64(uint64 volatile *addr, uint64 *old, uint64 new) 96 { 97 bool res; 98 99 runtime·lock(LOCK(addr)); 100 if(*addr == *old) { 101 *addr = new; 102 res = true; 103 } else { 104 *old = *addr; 105 res = false; 106 } 107 runtime·unlock(LOCK(addr)); 108 return res; 109 } 110 111 #pragma textflag 7 112 uint64 113 runtime·xadd64(uint64 volatile *addr, int64 delta) 114 { 115 uint64 res; 116 117 runtime·lock(LOCK(addr)); 118 res = *addr + delta; 119 *addr = res; 120 runtime·unlock(LOCK(addr)); 121 return res; 122 } 123 124 #pragma textflag 7 125 uint64 126 runtime·xchg64(uint64 volatile *addr, uint64 v) 127 { 128 uint64 res; 129 130 runtime·lock(LOCK(addr)); 131 res = *addr; 132 *addr = v; 133 runtime·unlock(LOCK(addr)); 134 return res; 135 } 136 137 #pragma textflag 7 138 uint64 139 runtime·atomicload64(uint64 volatile *addr) 140 { 141 uint64 res; 142 143 runtime·lock(LOCK(addr)); 144 res = *addr; 145 runtime·unlock(LOCK(addr)); 146 return res; 147 } 148 149 #pragma textflag 7 150 void 151 runtime·atomicstore64(uint64 volatile *addr, uint64 v) 152 { 153 runtime·lock(LOCK(addr)); 154 *addr = v; 155 runtime·unlock(LOCK(addr)); 156 }