mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1161170 - backport upstream fix for race in Cairo freed_pool. r=jrmuizel
This commit is contained in:
parent
09c83c61bd
commit
cb9bfa1888
@ -79,6 +79,18 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
|
||||
return __atomic_load_n(x, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
static cairo_always_inline cairo_atomic_int_t
|
||||
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
|
||||
{
|
||||
return __atomic_load_n(x, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
static cairo_always_inline void
|
||||
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
|
||||
{
|
||||
__atomic_store_n(x, val, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
static cairo_always_inline void *
|
||||
_cairo_atomic_ptr_get (void **x)
|
||||
{
|
||||
@ -154,6 +166,8 @@ _cairo_atomic_ptr_cmpxchg_return_old_impl(void **x, void *oldv, void *newv)
|
||||
typedef volatile long cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_get(x) ((int)*x)
|
||||
# define _cairo_atomic_int_get_relaxed(x) ((int)*(x))
|
||||
# define _cairo_atomic_int_set_relaxed(x, val) (*(x) = (val))
|
||||
# define _cairo_atomic_ptr_get(x) ((void*)*x)
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) InterlockedIncrement(x))
|
||||
@ -183,6 +197,18 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
|
||||
return *x;
|
||||
}
|
||||
|
||||
static cairo_always_inline cairo_atomic_int_t
|
||||
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
|
||||
{
|
||||
return *x;
|
||||
}
|
||||
|
||||
static cairo_always_inline void
|
||||
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
|
||||
{
|
||||
*x = val;
|
||||
}
|
||||
|
||||
static cairo_always_inline void *
|
||||
_cairo_atomic_ptr_get (void **x)
|
||||
{
|
||||
@ -191,6 +217,8 @@ _cairo_atomic_ptr_get (void **x)
|
||||
}
|
||||
#else
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_int_get_relaxed(x) (*(x))
|
||||
# define _cairo_atomic_int_set_relaxed(x, val) (*(x) = (val))
|
||||
# define _cairo_atomic_ptr_get(x) (*x)
|
||||
#endif
|
||||
|
||||
@ -225,6 +253,8 @@ typedef long long cairo_atomic_intptr_t;
|
||||
typedef AO_t cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_get(x) (AO_load_full (x))
|
||||
# define _cairo_atomic_int_get_relaxed(x) (AO_load_full (x))
|
||||
# define _cairo_atomic_int_set_relaxed(x, val) (AO_store_full ((x), (val)))
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1)
|
||||
@ -254,6 +284,8 @@ typedef unsigned long long cairo_atomic_intptr_t;
|
||||
typedef int32_t cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
|
||||
# define _cairo_atomic_int_get_relaxed(x) (*(x))
|
||||
# define _cairo_atomic_int_set_relaxed(x, val) (*(x) = (val))
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) OSAtomicIncrement32Barrier (x))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0)
|
||||
@ -309,9 +341,15 @@ _cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
cairo_private cairo_atomic_int_t
|
||||
_cairo_atomic_int_get (cairo_atomic_int_t *x);
|
||||
cairo_private cairo_atomic_int_t
|
||||
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x);
|
||||
void
|
||||
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val);
|
||||
# define _cairo_atomic_ptr_get(x) (void *) _cairo_atomic_int_get((cairo_atomic_int_t *) x)
|
||||
#else
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_int_get_relaxed(x) (*(x))
|
||||
# define _cairo_atomic_int_set_relaxed(x, val) (*(x) = (val))
|
||||
# define _cairo_atomic_ptr_get(x) (*x)
|
||||
#endif
|
||||
|
||||
|
@ -101,6 +101,20 @@ _cairo_atomic_int_get (cairo_atomic_intptr_t *x)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
cairo_atomic_intptr_t
|
||||
_cairo_atomic_int_get_relaxed (cairo_atomic_intptr_t *x)
|
||||
{
|
||||
return _cairo_atomic_int_get (x);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_atomic_int_set_relaxed (cairo_atomic_intptr_t *x, cairo_atomic_intptr_t val)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x = val;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -47,7 +47,7 @@
|
||||
#define MAX_FREED_POOL_SIZE 4
|
||||
typedef struct {
|
||||
void *pool[MAX_FREED_POOL_SIZE];
|
||||
int top;
|
||||
cairo_atomic_int_t top;
|
||||
} freed_pool_t;
|
||||
|
||||
static cairo_always_inline void *
|
||||
@ -77,13 +77,13 @@ _freed_pool_get (freed_pool_t *pool)
|
||||
void *ptr;
|
||||
int i;
|
||||
|
||||
i = pool->top - 1;
|
||||
i = _cairo_atomic_int_get_relaxed (&pool->top) - 1;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
ptr = _atomic_fetch (&pool->pool[i]);
|
||||
if (likely (ptr != NULL)) {
|
||||
pool->top = i;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, i);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -99,11 +99,11 @@ _freed_pool_put (freed_pool_t *pool, void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = pool->top;
|
||||
i = _cairo_atomic_int_get_relaxed (&pool->top);
|
||||
if (likely (i < ARRAY_LENGTH (pool->pool) &&
|
||||
_atomic_store (&pool->pool[i], ptr)))
|
||||
{
|
||||
pool->top = i + 1;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, i + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,13 +50,13 @@ _freed_pool_get_search (freed_pool_t *pool)
|
||||
for (i = ARRAY_LENGTH (pool->pool); i--;) {
|
||||
ptr = _atomic_fetch (&pool->pool[i]);
|
||||
if (ptr != NULL) {
|
||||
pool->top = i;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, i);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* empty */
|
||||
pool->top = 0;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -67,13 +67,13 @@ _freed_pool_put_search (freed_pool_t *pool, void *ptr)
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
|
||||
if (_atomic_store (&pool->pool[i], ptr)) {
|
||||
pool->top = i + 1;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, i + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* full */
|
||||
pool->top = i;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, i);
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ _freed_pool_reset (freed_pool_t *pool)
|
||||
pool->pool[i] = NULL;
|
||||
}
|
||||
|
||||
pool->top = 0;
|
||||
_cairo_atomic_int_set_relaxed (&pool->top, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user