[cairo-commit] src/cairo.c src/cairo-compiler-private.h

Andrea Canciani ranma42 at kemper.freedesktop.org
Sat Jun 25 08:04:47 PDT 2011


 src/cairo-compiler-private.h |   15 ------
 src/cairo.c                  |   94 +++++--------------------------------------
 2 files changed, 12 insertions(+), 97 deletions(-)

New commits:
commit f46ba56d5b8c54be5f0379aca204c0ce05d0f58a
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Sat Jun 25 15:35:48 2011 +0200

    Do not open-code freed-pool
    
    Reuse the freed-pool system to reduce allocation pressure of context
    creation/destruction.
    
    As a side effect, this removes the use of ffs() on Win32, cleaning up
    some MSVC-specific code and fixing a mingw-related build issue.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=30277

diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h
index 2bbd302..96034d6 100644
--- a/src/cairo-compiler-private.h
+++ b/src/cairo-compiler-private.h
@@ -219,21 +219,6 @@
 #ifdef _MSC_VER
 #undef inline
 #define inline __inline
-
-/* Add a definition of ffs */
-#include <intrin.h>
-#pragma intrinsic(_BitScanForward)
-static __forceinline int
-ffs (int x)
-{
-    unsigned long i;
-
-    if (_BitScanForward(&i, x) != 0)
-	return i + 1;
-
-    return 0;
-}
-
 #endif
 
 #if defined(_MSC_VER) && defined(_M_IX86)
diff --git a/src/cairo.c b/src/cairo.c
index dde9dac..42afe26 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -41,6 +41,7 @@
 
 #include "cairo-arc-private.h"
 #include "cairo-error-private.h"
+#include "cairo-freed-pool-private.h"
 #include "cairo-path-private.h"
 
 /**
@@ -177,85 +178,11 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status)
     _cairo_status_set_error (&cr->status, _cairo_error (status));
 }
 
-/* We keep a small stash of contexts to reduce malloc pressure */
-#define CAIRO_STASH_SIZE 4
-#if CAIRO_NO_MUTEX
-static struct {
-    cairo_t pool[CAIRO_STASH_SIZE];
-    int occupied;
-} _context_stash;
-
-static cairo_t *
-_context_get (void)
-{
-    int avail;
-
-    avail = ffs (~_context_stash.occupied) - 1;
-    if (avail >= CAIRO_STASH_SIZE)
-	return malloc (sizeof (cairo_t));
-
-    _context_stash.occupied |= 1 << avail;
-    return &_context_stash.pool[avail];
-}
-
-static void
-_context_put (cairo_t *cr)
-{
-    if (cr < &_context_stash.pool[0] ||
-	cr >= &_context_stash.pool[CAIRO_STASH_SIZE])
-    {
-	free (cr);
-	return;
-    }
-
-    _context_stash.occupied &= ~(1 << (cr - &_context_stash.pool[0]));
-}
-#elif HAS_ATOMIC_OPS
-static struct {
-    cairo_t pool[CAIRO_STASH_SIZE];
-    cairo_atomic_int_t occupied;
-} _context_stash;
-
-static cairo_t *
-_context_get (void)
-{
-    cairo_atomic_int_t avail, old, new;
-
-    do {
-	old = _cairo_atomic_int_get (&_context_stash.occupied);
-	avail = ffs (~old) - 1;
-	if (avail >= CAIRO_STASH_SIZE)
-	    return malloc (sizeof (cairo_t));
-
-	new = old | (1 << avail);
-    } while (! _cairo_atomic_int_cmpxchg (&_context_stash.occupied, old, new));
-
-    return &_context_stash.pool[avail];
-}
-
-static void
-_context_put (cairo_t *cr)
-{
-    cairo_atomic_int_t old, new, avail;
-
-    if (cr < &_context_stash.pool[0] ||
-	cr >= &_context_stash.pool[CAIRO_STASH_SIZE])
-    {
-	free (cr);
-	return;
-    }
-
-    avail = ~(1 << (cr - &_context_stash.pool[0]));
-    do {
-	old = _cairo_atomic_int_get (&_context_stash.occupied);
-	new = old & avail;
-    } while (! _cairo_atomic_int_cmpxchg (&_context_stash.occupied, old, new));
-}
-#else
-#define _context_get() malloc (sizeof (cairo_t))
-#define _context_put(cr) free (cr)
+#if HAS_FREED_POOL
+static freed_pool_t context_pool;
 #endif
 
+
 /* XXX This should disappear in favour of a common pool of error objects. */
 static cairo_t *_cairo_nil__objects[CAIRO_STATUS_LAST_STATUS + 1];
 
@@ -346,9 +273,12 @@ cairo_create (cairo_surface_t *target)
     if (unlikely (target->status))
 	return _cairo_create_in_error (target->status);
 
-    cr = _context_get ();
-    if (unlikely (cr == NULL))
-	return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+    cr = _freed_pool_get (&context_pool);
+    if (unlikely (cr == NULL)) {
+	cr = malloc (sizeof (cairo_t));
+	if (unlikely (cr == NULL))
+	    return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+    }
 
     CAIRO_REFERENCE_COUNT_INIT (&cr->ref_count, 1);
 
@@ -363,7 +293,7 @@ cairo_create (cairo_surface_t *target)
 
     status = _cairo_gstate_init (cr->gstate, target);
     if (unlikely (status)) {
-	_context_put (cr);
+	_freed_pool_put (&context_pool, cr);
 	cr = _cairo_create_in_error (status);
     }
 
@@ -436,7 +366,7 @@ cairo_destroy (cairo_t *cr)
     /* mark the context as invalid to protect against misuse */
     cr->status = CAIRO_STATUS_NULL_POINTER;
 
-    _context_put (cr);
+    _freed_pool_put (&context_pool, cr);
 }
 slim_hidden_def (cairo_destroy);
 


More information about the cairo-commit mailing list