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

Reply via email to