summaryrefslogtreecommitdiff
path: root/lib/librthread
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-01-27 08:40:06 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-01-27 08:40:06 +0000
commitd1e5520d3416e582a49f9a4c3bd7d63b5da7f401 (patch)
tree87fa933b67164201f9d90ec46af7eeb43dc6eb97 /lib/librthread
parenta8abe68c89c986c710d9956fe5f099ed3fbbb02c (diff)
Replace the malloc spinlock with a mutex. This lock is held over system calls
which run for many cycles and may even sleep. This leads to other threads spinning for a long time waiting on the lock. Using a mutex means those threads go to sleep and get woken up when the lock is released, which results in a lot less CPU usage. More work is needed to improve the performance of threaded code that suffers from malloc lock contention, but this diff makes ports like Firefox significantly more usable. Tested by many. ok mpi@, guenther@, tedu@, jca@
Diffstat (limited to 'lib/librthread')
-rw-r--r--lib/librthread/rthread.h3
-rw-r--r--lib/librthread/rthread_fork.c7
-rw-r--r--lib/librthread/rthread_libc.c25
3 files changed, 28 insertions, 7 deletions
diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h
index 1a73d61e4e0..0b699b525cb 100644
--- a/lib/librthread/rthread.h
+++ b/lib/librthread/rthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.h,v 1.54 2015/11/10 04:30:59 guenther Exp $ */
+/* $OpenBSD: rthread.h,v 1.55 2016/01/27 08:40:05 kettenis Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -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);
diff --git a/lib/librthread/rthread_fork.c b/lib/librthread/rthread_fork.c
index 18121278325..e6d632f90bf 100644
--- a/lib/librthread/rthread_fork.c
+++ b/lib/librthread/rthread_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_fork.c,v 1.14 2015/10/18 08:02:58 guenther Exp $ */
+/* $OpenBSD: rthread_fork.c,v 1.15 2016/01/27 08:40:05 kettenis Exp $ */
/*
* Copyright (c) 2008 Kurt Miller <kurt@openbsd.org>
@@ -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) {
diff --git a/lib/librthread/rthread_libc.c b/lib/librthread/rthread_libc.c
index 018368a84dd..8eff5369a83 100644
--- a/lib/librthread/rthread_libc.c
+++ b/lib/librthread/rthread_libc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_libc.c,v 1.12 2015/04/07 01:27:07 guenther Exp $ */
+/* $OpenBSD: rthread_libc.c,v 1.13 2016/01/27 08:40:05 kettenis Exp $ */
/* $snafu: libc_tag.c,v 1.4 2004/11/30 07:00:06 marc Exp $ */
/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
@@ -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;
}
/*