ref: 3071470d08a2c5b611bcb34f0ee8e3e7647c5254
parent: b927f42f5f6ebbe9af2a7650a9bd504f2f0cd808
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Dec 25 12:03:32 EST 2023
atomic: add crappy fallback implementations of atomics will anyone step up to write good ones?
--- /dev/null
+++ b/atomic-arm.c
@@ -1,0 +1,95 @@
+#include <u.h>
+#include <libc.h>
+
+#include "atomic.h"
+
+static Lock locktab[128];
+
+static u32int
+ihash(void *p)
+{
+ uintptr x = (uintptr)p;
+
+ /* constants from splitmix32 rng */
+ x = (x ^ (x >> 16)) * 0x85ebca6b;
+ x = (x ^ (x >> 13)) * 0xc2b2ae35;
+ x = (x ^ (x >> 16));
+ return x & (nelem(locktab)-1);
+}
+
+#define GET(T, n) \
+ T n(T *p) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ r = *p; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define SET(T, n) \
+ T n(T *p, T v) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ r = *p; \
+ *p = v; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define INC(T, n) \
+ T n(T *p, T dv) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ *p += dv; \
+ r = *p; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define CAS(T, n) \
+ int n(T *p, T ov, T nv) \
+ { \
+ uintptr h; \
+ int r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ if(*p == ov){ \
+ *p = nv; \
+ r = 1; \
+ }else \
+ r = 0; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+GET(int, ageti)
+GET(long, agetl)
+GET(vlong, agetv)
+GET(void*, agetp)
+
+SET(int, aseti)
+SET(long, asetl)
+SET(vlong, asetv)
+SET(void*, asetp)
+
+INC(int, ainci)
+INC(long, aincl)
+INC(vlong, aincv)
+
+CAS(int, acasi)
+CAS(long, acasl)
+CAS(vlong, acasv)
+CAS(void*, acasp)
--- /dev/null
+++ b/atomic-mips.c
@@ -1,0 +1,95 @@
+#include <u.h>
+#include <libc.h>
+
+#include "atomic.h"
+
+static Lock locktab[128];
+
+static u32int
+ihash(void *p)
+{
+ uintptr x = (uintptr)p;
+
+ /* constants from splitmix32 rng */
+ x = (x ^ (x >> 16)) * 0x85ebca6b;
+ x = (x ^ (x >> 13)) * 0xc2b2ae35;
+ x = (x ^ (x >> 16));
+ return x & (nelem(locktab)-1);
+}
+
+#define GET(T, n) \
+ T n(T *p) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ r = *p; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define SET(T, n) \
+ T n(T *p, T v) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ r = *p; \
+ *p = v; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define INC(T, n) \
+ T n(T *p, T dv) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ *p += dv; \
+ r = *p; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define CAS(T, n) \
+ int n(T *p, T ov, T nv) \
+ { \
+ uintptr h; \
+ int r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ if(*p == ov){ \
+ *p = nv; \
+ r = 1; \
+ }else \
+ r = 0; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+GET(int, ageti)
+GET(long, agetl)
+GET(vlong, agetv)
+GET(void*, agetp)
+
+SET(int, aseti)
+SET(long, asetl)
+SET(vlong, asetv)
+SET(void*, asetp)
+
+INC(int, ainci)
+INC(long, aincl)
+INC(vlong, aincv)
+
+CAS(int, acasi)
+CAS(long, acasl)
+CAS(vlong, acasv)
+CAS(void*, acasp)
--- /dev/null
+++ b/atomic-spim.c
@@ -1,0 +1,95 @@
+#include <u.h>
+#include <libc.h>
+
+#include "atomic.h"
+
+static Lock locktab[128];
+
+static u32int
+ihash(void *p)
+{
+ uintptr x = (uintptr)p;
+
+ /* constants from splitmix32 rng */
+ x = (x ^ (x >> 16)) * 0x85ebca6b;
+ x = (x ^ (x >> 13)) * 0xc2b2ae35;
+ x = (x ^ (x >> 16));
+ return x & (nelem(locktab)-1);
+}
+
+#define GET(T, n) \
+ T n(T *p) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ r = *p; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define SET(T, n) \
+ T n(T *p, T v) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ r = *p; \
+ *p = v; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define INC(T, n) \
+ T n(T *p, T dv) \
+ { \
+ uintptr h; \
+ T r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ *p += dv; \
+ r = *p; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+#define CAS(T, n) \
+ int n(T *p, T ov, T nv) \
+ { \
+ uintptr h; \
+ int r; \
+ \
+ h = ihash(p); \
+ lock(&locktab[h]); \
+ if(*p == ov){ \
+ *p = nv; \
+ r = 1; \
+ }else \
+ r = 0; \
+ unlock(&locktab[h]); \
+ return r; \
+ }
+
+GET(int, ageti)
+GET(long, agetl)
+GET(vlong, agetv)
+GET(void*, agetp)
+
+SET(int, aseti)
+SET(long, asetl)
+SET(vlong, asetv)
+SET(void*, asetp)
+
+INC(int, ainci)
+INC(long, aincl)
+INC(vlong, aincv)
+
+CAS(int, acasi)
+CAS(long, acasl)
+CAS(vlong, acasv)
+CAS(void*, acasp)