diff --git a/configure.in b/configure.in index aa7c1e785..5f7f613a6 100644 --- a/configure.in +++ b/configure.in @@ -89,6 +89,22 @@ dnl =========================================================================== AC_CHECK_FUNCS(vasnprintf) +dnl =========================================================================== +dnl +dnl Test for native atomic operations. +dnl +AC_MSG_CHECKING([for native atomic primitives]) +cairo_atomic_primitives="none" + +AC_TRY_COMPILE([int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); }], [], + AC_DEFINE(CAIRO_HAS_INTEL_ATOMIC_PRIMITIVES, 1, [Enable if your compiler supports the Intel __sync_* atomic primitives]) + cairo_atomic_primitives="Intel" + ) + +AC_MSG_RESULT([$cairo_atomic_primitives]) + +dnl =========================================================================== + AC_CHECK_LIBM LIBS="$LIBS $LIBM" diff --git a/src/Makefile.am b/src/Makefile.am index 85964e30c..2e6d2c60e 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 000000000..3577e0d32 --- /dev/null +++ b/src/cairo-atomic-private.h @@ -0,0 +1,81 @@ +/* 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 + */ + +#ifndef CAIRO_ATOMIC_PRIVATE_H +#define CAIRO_ATOMIC_PRIVATE_H + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +CAIRO_BEGIN_DECLS + +#define CAIRO_HAS_ATOMIC_OPS 1 + +#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 + +# include "cairo-compiler-private.h" + +# undef CAIRO_HAS_ATOMIC_OPS + +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 000000000..9941548b6 --- /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 + */ + +#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 abb4a9a3d..996079749 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