diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-01-27 08:40:06 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-01-27 08:40:06 +0000 |
commit | d1e5520d3416e582a49f9a4c3bd7d63b5da7f401 (patch) | |
tree | 87fa933b67164201f9d90ec46af7eeb43dc6eb97 /lib/librthread | |
parent | a8abe68c89c986c710d9956fe5f099ed3fbbb02c (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.h | 3 | ||||
-rw-r--r-- | lib/librthread/rthread_fork.c | 7 | ||||
-rw-r--r-- | lib/librthread/rthread_libc.c | 25 |
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; } /* |