[cairo-commit] 2 commits - src/cairo-atomic-private.h src/cairo-freed-pool.c src/cairo-freed-pool-private.h

Chris Wilson ickle at kemper.freedesktop.org
Thu May 20 13:58:48 PDT 2010


 src/cairo-atomic-private.h     |   16 ++++++++++++++++
 src/cairo-freed-pool-private.h |    8 +++++---
 src/cairo-freed-pool.c         |    4 +++-
 3 files changed, 24 insertions(+), 4 deletions(-)

New commits:
commit 2f0f4ed0e2ae5657dedfe180b7be3a2496753ba8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 20 21:54:51 2010 +0100

    freed-pool: Don't access beyond the end of the array.
    
    Argh. This bug has been here for quite some time and only showed itself
    with a corrupt pointer on ppc32. Since the erroneous write is inside the
    block, it remained undetected by valgrind.

diff --git a/src/cairo-freed-pool-private.h b/src/cairo-freed-pool-private.h
index 08fdd94..0a4ab0e 100644
--- a/src/cairo-freed-pool-private.h
+++ b/src/cairo-freed-pool-private.h
@@ -50,7 +50,7 @@ typedef struct {
     int top;
 } freed_pool_t;
 
-static inline void *
+static cairo_always_inline void *
 _atomic_fetch (void **slot)
 {
     void *ptr;
@@ -62,7 +62,7 @@ _atomic_fetch (void **slot)
     return ptr;
 }
 
-static inline cairo_bool_t
+static cairo_always_inline cairo_bool_t
 _atomic_store (void **slot, void *ptr)
 {
     return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr);
@@ -100,7 +100,9 @@ _freed_pool_put (freed_pool_t *pool, void *ptr)
     int i;
 
     i = pool->top;
-    if (likely (_atomic_store (&pool->pool[i], ptr))) {
+    if (likely (i < ARRAY_LENGTH (pool->pool) &&
+		_atomic_store (&pool->pool[i], ptr)))
+    {
 	pool->top = i + 1;
 	return;
     }
diff --git a/src/cairo-freed-pool.c b/src/cairo-freed-pool.c
index 9d42693..cfdc8e9 100644
--- a/src/cairo-freed-pool.c
+++ b/src/cairo-freed-pool.c
@@ -73,7 +73,7 @@ _freed_pool_put_search (freed_pool_t *pool, void *ptr)
     }
 
     /* full */
-    pool->top = ARRAY_LENGTH (pool->pool);
+    pool->top = i;
     free (ptr);
 }
 
@@ -86,6 +86,8 @@ _freed_pool_reset (freed_pool_t *pool)
 	free (pool->pool[i]);
 	pool->pool[i] = NULL;
     }
+
+    pool->top = 0;
 }
 
 #endif
commit 97b4aeba44e5f4b23b3ed417b991570b46d4736e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 20 21:54:16 2010 +0100

    atomic: Add memory barriers if required for intel primitives

diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index 572f849..8d02ec9 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -59,8 +59,24 @@ CAIRO_BEGIN_DECLS
 
 typedef int cairo_atomic_int_t;
 
+#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
+static cairo_always_inline cairo_atomic_int_t
+_cairo_atomic_int_get (cairo_atomic_int_t *x)
+{
+    __sync_synchronize ();
+    return *x;
+}
+
+static cairo_always_inline void *
+_cairo_atomic_ptr_get (void **x)
+{
+    __sync_synchronize ();
+    return *x;
+}
+#else
 # define _cairo_atomic_int_get(x) (*x)
 # define _cairo_atomic_ptr_get(x) (*x)
+#endif
 
 # 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)


More information about the cairo-commit mailing list