Mesa (master): gallium: Add simple atomic class api.

Thomas Hellstrom thomash at kemper.freedesktop.org
Mon Mar 16 10:41:44 UTC 2009


Module: Mesa
Branch: master
Commit: fc1ef97c3349588cd33a22dc88ab30b6f701000e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fc1ef97c3349588cd33a22dc88ab30b6f701000e

Author: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
Date:   Mon Mar 16 11:40:18 2009 +0100

gallium: Add simple atomic class api.

Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>

---

 src/gallium/include/pipe/p_atomic.h |  154 +++++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/src/gallium/include/pipe/p_atomic.h b/src/gallium/include/pipe/p_atomic.h
new file mode 100644
index 0000000..578d594
--- /dev/null
+++ b/src/gallium/include/pipe/p_atomic.h
@@ -0,0 +1,154 @@
+/**
+ * Many similar implementations exist. See for example libwsbm
+ * or the linux kernel include/atomic.h
+ *
+ * No copyright claimed on this file.
+ *
+ */
+
+#ifndef P_ATOMIC_H
+#define P_ATOMIC_H
+
+#include "p_defines.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(PIPE_CC_GCC))
+struct pipe_atomic {
+   int32_t count;
+};
+
+#define p_atomic_set(_v, _i) ((_v)->count = (_i))
+#define p_atomic_read(_v) ((_v)->count)
+
+
+static INLINE boolean
+p_atomic_dec_zero(struct pipe_atomic *v)
+{
+#ifdef __i386__
+   unsigned char c;
+
+   __asm__ __volatile__("lock; decl %0; sete %1":"+m"(v->count), "=qm"(c)
+			::"memory");
+
+   return c != 0;
+#else  /* __i386__*/
+   return (__sync_sub_and_fetch(&v->count, 1) == 0);
+#endif /* __i386__*/
+}
+
+static INLINE void
+p_atomic_inc(struct pipe_atomic *v)
+{
+#ifdef __i386__
+   __asm__ __volatile__("lock; incl %0":"+m"(v->count));
+#else /* __i386__*/
+   (void) __sync_add_and_fetch(&v->count, 1);
+#endif /* __i386__*/
+}
+
+static INLINE void
+p_atomic_dec(struct pipe_atomic *v)
+{
+#ifdef __i386__
+   __asm__ __volatile__("lock; decl %0":"+m"(v->count));
+#else /* __i386__*/
+   (void) __sync_sub_and_fetch(&v->count, 1);
+#endif /* __i386__*/
+}
+
+static INLINE int32_t
+p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t new)
+{
+   return __sync_val_compare_and_swap(&v->count, old, new);
+}
+
+#else /* (defined(PIPE_CC_GCC)) */
+
+#include "pipe/p_thread.h"
+
+/**
+ * This implementation should really not be used.
+ * Add an assembly port instead. It may abort and
+ * doesn't destroy used mutexes.
+ */
+
+struct pipe_atomic {
+   pipe_mutex mutex;
+   int32_t count;
+};
+
+static INLINE void
+p_atomic_set(struct pipe_atomic *v, int32_t i)
+{
+   int ret;
+   ret = pipe_mutex_init(v->mutex);
+   if (ret)
+      abort();
+   pipe_mutex_lock(v->mutex);
+   v->count = i;
+   pipe_mutex_unlock(v->mutex);
+}
+
+static INLINE int32_t
+p_atomic_read(struct pipe_atomic *v)
+{
+   int32_t ret;
+
+   pipe_mutex_lock(v->mutex);
+   ret = v->count;
+   pipe_mutex_unlock(v->mutex);
+   return ret;
+}
+
+static INLINE void
+p_atomic_inc(struct pipe_atomic *v)
+{
+   pipe_mutex_lock(v->mutex);
+   ++v->count;
+   pipe_mutex_unlock(v->mutex);
+}
+
+static INLINE void
+p_atomic_dec(struct pipe_atomic *v)
+{
+   pipe_mutex_lock(v->mutex);
+   --v->count;
+   pipe_mutex_unlock(v->mutex);
+}
+
+static INLINE boolean
+p_atomic_dec_zero(struct pipe_atomic *v)
+{
+   boolean ret;
+
+   pipe_mutex_lock(v->mutex);
+   ret = (--v->count == 0);
+   pipe_mutex_unlock(v->mutex);
+   return ret;
+}
+
+static INLINE int32_t
+p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t new)
+{
+   int32_t ret;
+
+   pipe_mutex_lock(v->mutex);
+   ret = v->count;
+   if (ret == old)
+      v->count = new;
+   pipe_mutex_unlock(v->mutex);
+
+   return ret;
+}
+
+#endif /* (defined(PIPE_CC_GCC)) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* P_ATOMIC_H */




More information about the mesa-commit mailing list