Firefox makes a lot of concurrent malloc(3) calls. The locking to make malloc(3) thread-safe is a bit...suboptimal. This diff makes things better by using a mutex instead of spinlock. If you're running Firefox you want to try it; it makes video watchable on some machines. If you're not running Firefox you want to try it; to make sure it doesn't break things.
Enjoy, Mark Index: rthread.h =================================================================== RCS file: /cvs/src/lib/librthread/rthread.h,v retrieving revision 1.54 diff -u -p -r1.54 rthread.h --- rthread.h 10 Nov 2015 04:30:59 -0000 1.54 +++ rthread.h 22 Jan 2016 21:08:11 -0000 @@ -223,6 +223,7 @@ void _rthread_debug_init(void); #ifndef NO_PIC void _rthread_dl_lock(int what); #endif +void _thread_malloc_reinit(void); /* rthread_cancel.c */ void _enter_cancel(pthread_t); Index: rthread_fork.c =================================================================== RCS file: /cvs/src/lib/librthread/rthread_fork.c,v retrieving revision 1.14 diff -u -p -r1.14 rthread_fork.c --- rthread_fork.c 18 Oct 2015 08:02:58 -0000 1.14 +++ rthread_fork.c 22 Jan 2016 21:08:11 -0000 @@ -82,7 +82,10 @@ _dofork(int is_vfork) newid = sys_fork(); _thread_arc4_unlock(); - _thread_malloc_unlock(); + if (newid == 0) + _thread_malloc_reinit(); + else + _thread_malloc_unlock(); _thread_atexit_unlock(); if (newid == 0) { Index: rthread_libc.c =================================================================== RCS file: /cvs/src/lib/librthread/rthread_libc.c,v retrieving revision 1.12 diff -u -p -r1.12 rthread_libc.c --- rthread_libc.c 7 Apr 2015 01:27:07 -0000 1.12 +++ rthread_libc.c 22 Jan 2016 21:08:11 -0000 @@ -152,18 +152,35 @@ _thread_mutex_destroy(void **mutex) /* * the malloc lock */ -static struct _spinlock malloc_lock = _SPINLOCK_UNLOCKED; +static struct pthread_mutex malloc_lock = { + _SPINLOCK_UNLOCKED, + TAILQ_HEAD_INITIALIZER(malloc_lock.lockers), + PTHREAD_MUTEX_DEFAULT, + NULL, + 0, + -1 +}; +static pthread_mutex_t malloc_mutex = &malloc_lock; void _thread_malloc_lock(void) { - _spinlock(&malloc_lock); + pthread_mutex_lock(&malloc_mutex); } void _thread_malloc_unlock(void) { - _spinunlock(&malloc_lock); + pthread_mutex_unlock(&malloc_mutex); +} + +void +_thread_malloc_reinit(void) +{ + malloc_lock.lock = _SPINLOCK_UNLOCKED_ASSIGN; + TAILQ_INIT(&malloc_lock.lockers); + malloc_lock.owner = NULL; + malloc_lock.count = 0; } /*