summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2016-01-27 08:40:05 +0000
committerkettenis <kettenis@openbsd.org>2016-01-27 08:40:05 +0000
commit45759446f8ab613ae1e416f195406bd5fd02d070 (patch)
tree0ba70fd344a38cb751b3dab14ed265d45e19f952
parentsend events to filters in a simple loop, rather than using the (diff)
downloadwireguard-openbsd-45759446f8ab613ae1e416f195406bd5fd02d070.tar.xz
wireguard-openbsd-45759446f8ab613ae1e416f195406bd5fd02d070.zip
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@
-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;
}
/*