Use OSSpinLock*() for locking on OS X.
pthread_mutex_lock() can call malloc() on OS X (!!!), which causes deadlock. Work around this by using spinlocks that are built of more primitive stuff.
This commit is contained in:
parent
763baa6cfc
commit
893a0ed7c8
@ -792,6 +792,21 @@ if test "x${osatomic}" = "xyes" ; then
|
|||||||
AC_DEFINE([JEMALLOC_OSATOMIC])
|
AC_DEFINE([JEMALLOC_OSATOMIC])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ============================================================================
|
||||||
|
dnl Check for spinlock(3) operations as provided on Darwin.
|
||||||
|
|
||||||
|
JE_COMPILABLE([Darwin OSSpin*()], [
|
||||||
|
#include <libkern/OSAtomic.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
], [
|
||||||
|
OSSpinLock lock = 0;
|
||||||
|
OSSpinLockLock(&lock);
|
||||||
|
OSSpinLockUnlock(&lock);
|
||||||
|
], [osspin])
|
||||||
|
if test "x${osspin}" = "xyes" ; then
|
||||||
|
AC_DEFINE([JEMALLOC_OSSPIN])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl ============================================================================
|
dnl ============================================================================
|
||||||
dnl Check for allocator-related functions that should be wrapped.
|
dnl Check for allocator-related functions that should be wrapped.
|
||||||
|
|
||||||
|
@ -13,13 +13,19 @@
|
|||||||
#define atomic_read_uint32(p) atomic_add_uint32(p, 0)
|
#define atomic_read_uint32(p) atomic_add_uint32(p, 0)
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3)
|
#if (LG_SIZEOF_PTR == 3)
|
||||||
# define atomic_read_z(p) atomic_add_uint64(p, 0)
|
# define atomic_read_z(p) \
|
||||||
# define atomic_add_z(p, x) atomic_add_uint64(p, x)
|
(size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)0)
|
||||||
# define atomic_sub_z(p, x) atomic_sub_uint64(p, x)
|
# define atomic_add_z(p, x) \
|
||||||
|
(size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x)
|
||||||
|
# define atomic_sub_z(p, x) \
|
||||||
|
(size_t)atomic_sub_uint64((uint64_t *)p, (uint64_t)x)
|
||||||
#elif (LG_SIZEOF_PTR == 2)
|
#elif (LG_SIZEOF_PTR == 2)
|
||||||
# define atomic_read_z(p) atomic_add_uint32(p, 0)
|
# define atomic_read_z(p) \
|
||||||
# define atomic_add_z(p, x) atomic_add_uint32(p, x)
|
(size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)0)
|
||||||
# define atomic_sub_z(p, x) atomic_sub_uint32(p, x)
|
# define atomic_add_z(p, x) \
|
||||||
|
(size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x)
|
||||||
|
# define atomic_sub_z(p, x) \
|
||||||
|
(size_t)atomic_sub_uint32((uint32_t *)p, (uint32_t)x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* JEMALLOC_H_EXTERNS */
|
#endif /* JEMALLOC_H_EXTERNS */
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#define JEMALLOC_MANGLE
|
#define JEMALLOC_MANGLE
|
||||||
#include "../jemalloc@install_suffix@.h"
|
#include "../jemalloc@install_suffix@.h"
|
||||||
|
|
||||||
#ifdef JEMALLOC_OSATOMIC
|
#if (defined(JEMALLOC_OSATOMIC) || defined(JEMALLOC_OSSPIN))
|
||||||
#include <libkern/OSAtomic.h>
|
#include <libkern/OSAtomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
#ifdef JEMALLOC_H_TYPES
|
#ifdef JEMALLOC_H_TYPES
|
||||||
|
|
||||||
|
#ifdef JEMALLOC_OSSPIN
|
||||||
|
typedef OSSpinLock malloc_mutex_t;
|
||||||
|
#else
|
||||||
typedef pthread_mutex_t malloc_mutex_t;
|
typedef pthread_mutex_t malloc_mutex_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||||
# define MALLOC_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
# define MALLOC_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||||
@ -41,17 +45,26 @@ JEMALLOC_INLINE void
|
|||||||
malloc_mutex_lock(malloc_mutex_t *mutex)
|
malloc_mutex_lock(malloc_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (isthreaded)
|
if (isthreaded) {
|
||||||
|
#ifdef JEMALLOC_OSSPIN
|
||||||
|
OSSpinLockLock(mutex);
|
||||||
|
#else
|
||||||
pthread_mutex_lock(mutex);
|
pthread_mutex_lock(mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE bool
|
JEMALLOC_INLINE bool
|
||||||
malloc_mutex_trylock(malloc_mutex_t *mutex)
|
malloc_mutex_trylock(malloc_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (isthreaded)
|
if (isthreaded) {
|
||||||
|
#ifdef JEMALLOC_OSSPIN
|
||||||
|
return (OSSpinLockTry(mutex) == false);
|
||||||
|
#else
|
||||||
return (pthread_mutex_trylock(mutex) != 0);
|
return (pthread_mutex_trylock(mutex) != 0);
|
||||||
else
|
#endif
|
||||||
|
} else
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +72,13 @@ JEMALLOC_INLINE void
|
|||||||
malloc_mutex_unlock(malloc_mutex_t *mutex)
|
malloc_mutex_unlock(malloc_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (isthreaded)
|
if (isthreaded) {
|
||||||
|
#ifdef JEMALLOC_OSSPIN
|
||||||
|
OSSpinLockUnlock(mutex);
|
||||||
|
#else
|
||||||
pthread_mutex_unlock(mutex);
|
pthread_mutex_unlock(mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
*/
|
*/
|
||||||
#undef JEMALLOC_OSATOMIC
|
#undef JEMALLOC_OSATOMIC
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defined if OSSpin*() functions are available, as provided by Darwin, and
|
||||||
|
* documented in the spinlock(3) manual page.
|
||||||
|
*/
|
||||||
|
#undef JEMALLOC_OSSPIN
|
||||||
|
|
||||||
/* Defined if __attribute__((...)) syntax is supported. */
|
/* Defined if __attribute__((...)) syntax is supported. */
|
||||||
#undef JEMALLOC_HAVE_ATTR
|
#undef JEMALLOC_HAVE_ATTR
|
||||||
#ifdef JEMALLOC_HAVE_ATTR
|
#ifdef JEMALLOC_HAVE_ATTR
|
||||||
|
@ -28,7 +28,13 @@ static bool malloc_initialized = false;
|
|||||||
static pthread_t malloc_initializer = (unsigned long)0;
|
static pthread_t malloc_initializer = (unsigned long)0;
|
||||||
|
|
||||||
/* Used to avoid initialization races. */
|
/* Used to avoid initialization races. */
|
||||||
static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER;
|
static malloc_mutex_t init_lock =
|
||||||
|
#ifdef JEMALLOC_OSSPIN
|
||||||
|
0
|
||||||
|
#else
|
||||||
|
MALLOC_MUTEX_INITIALIZER
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
#ifdef DYNAMIC_PAGE_SHIFT
|
#ifdef DYNAMIC_PAGE_SHIFT
|
||||||
size_t pagesize;
|
size_t pagesize;
|
||||||
|
@ -55,6 +55,9 @@ pthread_create(pthread_t *__restrict thread,
|
|||||||
bool
|
bool
|
||||||
malloc_mutex_init(malloc_mutex_t *mutex)
|
malloc_mutex_init(malloc_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
#ifdef JEMALLOC_OSSPIN
|
||||||
|
*mutex = 0;
|
||||||
|
#else
|
||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
|
|
||||||
if (pthread_mutexattr_init(&attr) != 0)
|
if (pthread_mutexattr_init(&attr) != 0)
|
||||||
@ -70,6 +73,7 @@ malloc_mutex_init(malloc_mutex_t *mutex)
|
|||||||
}
|
}
|
||||||
pthread_mutexattr_destroy(&attr);
|
pthread_mutexattr_destroy(&attr);
|
||||||
|
|
||||||
|
#endif
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +81,10 @@ void
|
|||||||
malloc_mutex_destroy(malloc_mutex_t *mutex)
|
malloc_mutex_destroy(malloc_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef JEMALLOC_OSSPIN
|
||||||
if (pthread_mutex_destroy(mutex) != 0) {
|
if (pthread_mutex_destroy(mutex) != 0) {
|
||||||
malloc_write("<jemalloc>: Error in pthread_mutex_destroy()\n");
|
malloc_write("<jemalloc>: Error in pthread_mutex_destroy()\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user