Loading...
darwin/OSAtomicLoadStoreEx.c /dev/null Libc-825.24
--- /dev/null
+++ Libc/Libc-825.24/darwin/OSAtomicLoadStoreEx.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2011 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+// OSAtomic.h is included by files that include this C file.
+/* #include "OSAtomic.h" */
+
+int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAdd32);
+int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicAdd32);
+	int32_t r;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		r += v;
+		_osatomic_store_exclusive(p, r, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p) _OSATOMIC_VARIANT_B(OSAtomicAdd64);
+int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicAdd64);
+
+	int64_t r;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive64(p, r);
+		r += v;
+		_osatomic_store_exclusive64(p, r, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int32_t OSAtomicOr32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicOr32);
+int32_t OSAtomicOr32(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicOr32);
+	int32_t r;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		r |= v;
+		_osatomic_store_exclusive(p, r, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int32_t OSAtomicOr32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicOr32Orig);
+int32_t OSAtomicOr32Orig(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicOr32Orig);
+	int32_t r, n;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		n = r | v;
+		_osatomic_store_exclusive(p, n, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int32_t OSAtomicAnd32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAnd32);
+int32_t OSAtomicAnd32(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicAnd32);
+	int32_t r;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		r &= v;
+		_osatomic_store_exclusive(p, r, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int32_t OSAtomicAnd32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAnd32Orig);
+int32_t OSAtomicAnd32Orig(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicAnd32Orig);
+	int32_t r, n;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		n = r & v;
+		_osatomic_store_exclusive(p, n, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int32_t OSAtomicXor32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicXor32);
+int32_t OSAtomicXor32(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicXor32);
+	int32_t r;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		r ^= v;
+		_osatomic_store_exclusive(p, r, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+int32_t OSAtomicXor32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicXor32Orig);
+int32_t OSAtomicXor32Orig(int32_t v, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicXor32Orig);
+	int32_t r, n;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(p, r);
+		n = r ^ v;
+		_osatomic_store_exclusive(p, n, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap32);
+bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p)
+{
+	_OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapInt, OSAtomicCompareAndSwap32);
+
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap32);
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapInt);
+#ifndef __LP64__
+	_OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong, OSAtomicCompareAndSwap32);
+	_OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr, OSAtomicCompareAndSwap32);
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong);
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr);
+#endif
+
+	int32_t r;
+	uint32_t t;
+
+	do {
+		_osatomic_load_exclusive(p, r);
+		if (r != o) return false;
+		_osatomic_store_barrier();
+		_osatomic_store_exclusive(p, n, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return true;
+}
+
+bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap64);
+bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap64);
+#ifdef __LP64__
+	_OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong, OSAtomicCompareAndSwap64);
+	_OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr, OSAtomicCompareAndSwap64);
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong);
+	_OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr);
+#endif
+
+	int64_t r;
+	uint32_t t;
+
+	do {
+		_osatomic_load_exclusive64(p, r);
+		if (r != o) return false;
+		_osatomic_store_barrier();
+		_osatomic_store_exclusive64(p, n, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return true;
+}
+
+#if defined(_OSATOMIC_EXTRAS)
+
+void OSMemoryBarrier(void) _OSATOMIC_VARIANT(OSMemoryBarrier);
+void OSMemoryBarrier(void)
+{
+	_osatomic_barrier();
+}
+
+typedef volatile struct {
+	void	*item;
+	long	 unused;
+} OSQueueHead;
+
+void OSAtomicEnqueue(OSQueueHead *l, void *n, size_t o) _OSATOMIC_VARIANT(OSAtomicEnqueue);
+void OSAtomicEnqueue(OSQueueHead *l, void *n, size_t o)
+{
+	void ** r = (void **)((char *)n + o);
+	void * volatile * i = (void **)&(l->item);
+	void * q;
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(i, q);
+		*r = q;
+		_osatomic_store_exclusive(i, n, t);
+	} while (slowpath(t));
+	_osatomic_barrier();
+}
+
+void* OSAtomicDequeue(OSQueueHead *l, size_t o) _OSATOMIC_VARIANT(OSAtomicDequeue);
+void* OSAtomicDequeue(OSQueueHead *l, size_t o)
+{
+	void * h;
+	void ** r;
+	void * volatile * i = (void **)&(l->item);
+	uint32_t t;
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(i, r);
+		if (!r) return NULL;
+		h = *(void **)((char *)r + o);
+		_osatomic_store_exclusive(i, h, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return r;
+}
+
+#endif
+
+bool OSAtomicTestAndSet(uint32_t n, volatile void * p) _OSATOMIC_VARIANT_B(OSAtomicTestAndSet);
+bool OSAtomicTestAndSet(uint32_t n, volatile void * p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicTestAndSet);
+	uint32_t * ptr = (uint32_t *)((char *)p + (4 * (n / 32)));
+	uint32_t i, r, t;
+
+	n = (0x80 >> (n & 7)) << (n & ~7 & 31);
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(ptr, r);
+		i = r | n;
+		if (i == r) break;
+		_osatomic_store_exclusive(ptr, i, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return ((r & n) != 0);
+}
+
+bool OSAtomicTestAndClear(uint32_t n, volatile void * p) _OSATOMIC_VARIANT_B(OSAtomicTestAndClear);
+bool OSAtomicTestAndClear(uint32_t n, volatile void * p)
+{
+	_OSATOMIC_ALIAS_NB(OSAtomicTestAndClear);
+	uint32_t * ptr = (uint32_t *)((char *)p + (4 * (n / 32)));
+	uint32_t i, r, t;
+
+	n = (0x80 >> (n & 7)) << (n & ~7 & 31);
+
+	_osatomic_store_barrier();
+	do {
+		_osatomic_load_exclusive(ptr, r);
+		i = r & ~n;
+		if (i == r) break;
+		_osatomic_store_exclusive(ptr, i, t);
+	} while (slowpath(t));
+
+	_osatomic_barrier();
+	return ((r & n) != 0);
+}
+