Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/drm2/include/linux Add atomic_long.



details:   https://anonhg.NetBSD.org/src/rev/25c4bab8624c
branches:  trunk
changeset: 992920:25c4bab8624c
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Aug 27 13:58:16 2018 +0000

description:
Add atomic_long.

diffstat:

 sys/external/bsd/drm2/include/linux/atomic.h |  64 +++++++++++++++++++++++++++-
 1 files changed, 63 insertions(+), 1 deletions(-)

diffs (78 lines):

diff -r d2d7ae473ee0 -r 25c4bab8624c sys/external/bsd/drm2/include/linux/atomic.h
--- a/sys/external/bsd/drm2/include/linux/atomic.h      Mon Aug 27 13:58:04 2018 +0000
+++ b/sys/external/bsd/drm2/include/linux/atomic.h      Mon Aug 27 13:58:16 2018 +0000
@@ -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 @@
        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)
 {



Home | Main Index | Thread Index | Old Index