summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/atomic_arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/atomic_arm.c')
-rw-r--r--src/pkg/runtime/atomic_arm.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/pkg/runtime/atomic_arm.c b/src/pkg/runtime/atomic_arm.c
index 52e4059ae..0b54840cc 100644
--- a/src/pkg/runtime/atomic_arm.c
+++ b/src/pkg/runtime/atomic_arm.c
@@ -3,6 +3,14 @@
// license that can be found in the LICENSE file.
#include "runtime.h"
+#include "arch_GOARCH.h"
+
+static union {
+ Lock l;
+ byte pad [CacheLineSize];
+} locktab[57];
+
+#define LOCK(addr) (&locktab[((uintptr)(addr)>>3)%nelem(locktab)].l)
// Atomic add and return new value.
#pragma textflag 7
@@ -80,4 +88,56 @@ runtime·atomicstore(uint32 volatile* addr, uint32 v)
if(runtime·cas(addr, old, v))
return;
}
-} \ No newline at end of file
+}
+
+#pragma textflag 7
+bool
+runtime·cas64(uint64 volatile *addr, uint64 *old, uint64 new)
+{
+ bool res;
+
+ runtime·lock(LOCK(addr));
+ if(*addr == *old) {
+ *addr = new;
+ res = true;
+ } else {
+ *old = *addr;
+ res = false;
+ }
+ runtime·unlock(LOCK(addr));
+ return res;
+}
+
+#pragma textflag 7
+uint64
+runtime·xadd64(uint64 volatile *addr, int64 delta)
+{
+ uint64 res;
+
+ runtime·lock(LOCK(addr));
+ res = *addr + delta;
+ *addr = res;
+ runtime·unlock(LOCK(addr));
+ return res;
+}
+
+#pragma textflag 7
+uint64
+runtime·atomicload64(uint64 volatile *addr)
+{
+ uint64 res;
+
+ runtime·lock(LOCK(addr));
+ res = *addr;
+ runtime·unlock(LOCK(addr));
+ return res;
+}
+
+#pragma textflag 7
+void
+runtime·atomicstore64(uint64 volatile *addr, uint64 v)
+{
+ runtime·lock(LOCK(addr));
+ *addr = v;
+ runtime·unlock(LOCK(addr));
+}