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;
}
/*