Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 27 13:58:16 UTC 2018

Modified Files:
        src/sys/external/bsd/drm2/include/linux: atomic.h

Log Message:
Add atomic_long.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/external/bsd/drm2/include/linux/atomic.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/include/linux/atomic.h
diff -u src/sys/external/bsd/drm2/include/linux/atomic.h:1.13 src/sys/external/bsd/drm2/include/linux/atomic.h:1.14
--- src/sys/external/bsd/drm2/include/linux/atomic.h:1.13	Mon Aug 27 13:41:08 2018
+++ src/sys/external/bsd/drm2/include/linux/atomic.h	Mon Aug 27 13:58:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: atomic.h,v 1.13 2018/08/27 13:41:08 riastradh Exp $	*/
+/*	$NetBSD: atomic.h,v 1.14 2018/08/27 13:58:16 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -286,6 +286,68 @@ atomic64_cmpxchg(struct atomic64 *atomic
 	return old;
 }
 
+struct atomic_long {
+	volatile unsigned long	al_v;
+};
+
+typedef struct atomic_long atomic_long_t;
+
+static inline long
+atomic_long_read(struct atomic_long *a)
+{
+	/* no membar */
+	return (unsigned long)a->al_v;
+}
+
+static inline void
+atomic_long_set(struct atomic_long *a, long v)
+{
+	/* no membar */
+	a->al_v = v;
+}
+
+static inline long
+atomic_long_add_unless(struct atomic_long *a, long addend, long zero)
+{
+	long value;
+
+	smp_mb__before_atomic();
+	do {
+		value = (long)a->al_v;
+		if (value == zero)
+			break;
+	} while (atomic_cas_ulong(&a->al_v, (unsigned long)value,
+		(unsigned long)(value + addend)) != (unsigned long)value);
+	smp_mb__after_atomic();
+
+	return value != zero;
+}
+
+static inline long
+atomic_long_inc_not_zero(struct atomic_long *a)
+{
+	/* membar implied by atomic_long_add_unless */
+	return atomic_long_add_unless(a, 1, 0);
+}
+
+static inline long
+atomic_long_cmpxchg(struct atomic_long *a, long expect, long new)
+{
+	long old;
+
+	/*
+	 * XXX As an optimization, under Linux's semantics we are
+	 * allowed to skip the memory barrier if the comparison fails,
+	 * but taking advantage of that is not convenient here.
+	 */
+	smp_mb__before_atomic();
+	old = (long)atomic_cas_ulong(&a->al_v, (unsigned long)expect,
+	    (unsigned long)new);
+	smp_mb__after_atomic();
+
+	return old;
+}
+
 static inline void
 set_bit(unsigned int bit, volatile unsigned long *ptr)
 {

Reply via email to