[PATCH] [cairo-atomic] Introduce atomic ops.

Chris Wilson chris at chris-wilson.co.uk
Fri Sep 21 02:45:55 PDT 2007


Test for the availability of the Intel __sync_* atomic primitives and
use them to define a few operations useful for reference counting -
providing a generic interface that may be targeted at more architectures
in the future. If no atomic primitives are available, use a mutex based
variant. If the contention on that mutex is too high, we can consider
using an array of mutexes using the address of the atomic variable as
the hash.
---
 configure.in                   |   11 +++++
 src/Makefile.am                |    2 +
 src/cairo-atomic-private.h     |   80 ++++++++++++++++++++++++++++++++++++++++
 src/cairo-atomic.c             |   79 +++++++++++++++++++++++++++++++++++++++
 src/cairo-mutex-list-private.h |    3 +
 5 files changed, 175 insertions(+), 0 deletions(-)

diff --git a/configure.in b/configure.in
index aa7c1e7..5c49f66 100644
--- a/configure.in
+++ b/configure.in
@@ -89,6 +89,17 @@ dnl ===========================================================================
 
 AC_CHECK_FUNCS(vasnprintf)
 	
+AC_ARG_ENABLE(atomics,
+  AS_HELP_STRING([--disable-atomics],
+		 [Do not use atomic operations]),
+  [use_atomic=$enableval], [use_atomic=auto])
+if test "x$use_atomic" != "xno"; then
+    AC_TRY_COMPILE([int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); }], [],
+      AC_DEFINE(CAIRO_HAS_ATOMIC_OPS, 1, [Enable if your platform has native atomic operations])
+      AC_DEFINE(CAIRO_HAS_INTEL_ATOMIC_PRIMITIVES, 1, [Enable if your compiler supports the Intel __sync_* atomic primitives])
+      )
+fi
+
 AC_CHECK_LIBM
 LIBS="$LIBS $LIBM"
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 85964e3..2e6d2c6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -172,6 +172,8 @@ libcairo_la_base_sources =			\
 	cairo-arc.c				\
 	cairo-arc-private.h			\
 	cairo-array.c				\
+	cairo-atomic.c				\
+	cairo-atomic-private.h			\
 	cairo-base85-stream.c			\
 	cairo-bentley-ottmann.c			\
 	cairo-cache.c				\
diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
new file mode 100644
index 0000000..c027c13
--- /dev/null
+++ b/src/cairo-atomic-private.h
@@ -0,0 +1,80 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#ifndef CAIRO_ATOMIC_PRIVATE_H
+#define CAIRO_ATOMIC_PRIVATE_H
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+CAIRO_BEGIN_DECLS
+
+#if CAIRO_HAS_ATOMIC_OPS
+
+#if CAIRO_HAS_INTEL_ATOMIC_PRIMITIVES
+typedef int cairo_atomic_int_t;
+#define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
+#define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
+#define _cairo_atomic_int_get(x) (*x)
+#define _cairo_atomic_int_set(x, value) ((*x) = value)
+#else
+#error "Cairo tried to use native atomic operations without a valid architectural implementation"
+#endif
+
+#else
+
+#include "cairo-compiler-private.h"
+
+typedef int cairo_atomic_int_t;
+
+cairo_private void
+_cairo_atomic_int_inc (int *x);
+
+cairo_private cairo_bool_t
+_cairo_atomic_int_dec_and_test (int *x);
+
+cairo_private int
+_cairo_atomic_int_get (int *x);
+
+cairo_private void
+_cairo_atomic_int_set (int *x, int value);
+
+#endif
+
+CAIRO_END_DECLS
+
+#endif
diff --git a/src/cairo-atomic.c b/src/cairo-atomic.c
new file mode 100644
index 0000000..9941548
--- /dev/null
+++ b/src/cairo-atomic.c
@@ -0,0 +1,79 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-atomic-private.h"
+#include "cairo-mutex-private.h"
+
+#ifndef CAIRO_HAS_ATOMIC_OPS
+void
+_cairo_atomic_int_inc (int *x)
+{
+    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
+    *x += 1;
+    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
+}
+
+cairo_bool_t
+_cairo_atomic_int_dec_and_test (int *x)
+{
+    cairo_bool_t ret;
+
+    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
+    ret = --*x == 0;
+    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
+
+    return ret;
+}
+
+int
+_cairo_atomic_int_get (int *x)
+{
+    int ret;
+
+    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
+    ret = *x;
+    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
+
+    return ret;
+}
+
+void
+_cairo_atomic_int_set (int *x, int value)
+{
+    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
+    *x = value;
+    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
+}
+#endif
diff --git a/src/cairo-mutex-list-private.h b/src/cairo-mutex-list-private.h
index abb4a9a..9960797 100644
--- a/src/cairo-mutex-list-private.h
+++ b/src/cairo-mutex-list-private.h
@@ -46,6 +46,9 @@ CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex);
 CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex);
 #endif
 
+#ifndef CAIRO_HAS_ATOMIC_OPS
+CAIRO_MUTEX_DECLARE (_cairo_atomic_mutex);
+#endif
 
 /* Undefine, to err on unintended inclusion */
 #undef   CAIRO_MUTEX_DECLARE
-- 
1.4.4.2


--df+09Je9rNq3P+GE
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="0003-cairo-atomic-Rewrite-reference-counting-using-atomic-ops.txt"
Content-Transfer-Encoding: 8bit



More information about the cairo mailing list