Skip to content

Commit

Permalink
Bug 1026864: prevent malloc from calling wrapped pthread_mutex_lock a…
Browse files Browse the repository at this point in the history
…nd get rid of LibcAllocator. r=cyu,r=glandium,r=khuey
  • Loading branch information
Patrick Wang (Chih-Kai Wang) committed Jun 25, 2014
1 parent bba364f commit 01cc0c8
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 46 deletions.
3 changes: 3 additions & 0 deletions memory/jemalloc/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ if CONFIG['OS_TARGET'] == 'Linux':
# For mremap
DEFINES['_GNU_SOURCE'] = True

if CONFIG['MOZ_NUWA_PROCESS'] and CONFIG['MOZ_JEMALLOC3']:
DEFINES['pthread_mutex_lock'] = '__real_pthread_mutex_lock';

DEFINES['abort'] = 'moz_abort'

GENERATED_INCLUDES += ['src/include']
Expand Down
3 changes: 3 additions & 0 deletions memory/mozjemalloc/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ DEFINES['MOZ_JEMALLOC_IMPL'] = True
if CONFIG['OS_TARGET'] == 'Linux':
NO_PGO = True

if CONFIG['MOZ_NUWA_PROCESS']:
DEFINES['pthread_mutex_lock'] = '__real_pthread_mutex_lock';

LOCAL_INCLUDES += [
'/memory/build',
]
Expand Down
47 changes: 1 addition & 46 deletions mozglue/build/Nuwa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,52 +91,7 @@ static bool sNuwaForking = false;
static NuwaProtoFdInfo sProtoFdInfos[NUWA_TOPLEVEL_MAX];
static int sProtoFdInfosSize = 0;

template <typename T>
struct LibcAllocator: public std::allocator<T>
{
LibcAllocator()
{
void* libcHandle = dlopen("libc.so", RTLD_LAZY);
mMallocImpl = reinterpret_cast<void*(*)(size_t)>(dlsym(libcHandle, "malloc"));
mFreeImpl = reinterpret_cast<void(*)(void*)>(dlsym(libcHandle, "free"));

if (!(mMallocImpl && mFreeImpl)) {
// libc should be available, or we'll deadlock in using TLSInfoList.
abort();
}
}

inline typename std::allocator<T>::pointer
allocate(typename std::allocator<T>::size_type n,
const void * = 0)
{
return reinterpret_cast<T *>(mMallocImpl(sizeof(T) * n));
}

inline void
deallocate(typename std::allocator<T>::pointer p,
typename std::allocator<T>::size_type n)
{
mFreeImpl(p);
}

template<typename U>
struct rebind
{
typedef LibcAllocator<U> other;
};
private:
void* (*mMallocImpl)(size_t);
void (*mFreeImpl)(void*);
};

/**
* TLSInfoList should use malloc() and free() in libc to avoid the deadlock that
* jemalloc calls into __wrap_pthread_mutex_lock() and then deadlocks while
* the same thread already acquired sThreadCountLock.
*/
typedef std::vector<std::pair<pthread_key_t, void *>,
LibcAllocator<std::pair<pthread_key_t, void *> > >
typedef std::vector<std::pair<pthread_key_t, void *> >
TLSInfoList;

/**
Expand Down

0 comments on commit 01cc0c8

Please sign in to comment.