If a libpthread internal spinlock is held, nanosleep() for a tick instead of
yielding. This is a nasty band-aid but with many threads, looping over sched_yield() wastes a huge amount of CPU time. It would be nice to have a way to temporarily disable preemption, but it turns out that's yet another no-brain concept that has been patented and the patent holder seems to be suing people lately. Another alternative is probably to have kernel-assisted spinlocks.
This commit is contained in:
parent
513227e941
commit
c67dc640cd
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pthread_lock.c,v 1.24 2007/08/16 23:37:08 ad Exp $ */
|
||||
/* $NetBSD: pthread_lock.c,v 1.25 2007/09/07 00:07:54 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: pthread_lock.c,v 1.24 2007/08/16 23:37:08 ad Exp $");
|
||||
__RCSID("$NetBSD: pthread_lock.c,v 1.25 2007/09/07 00:07:54 ad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/lock.h>
|
||||
|
@ -51,6 +51,7 @@ __RCSID("$NetBSD: pthread_lock.c,v 1.24 2007/08/16 23:37:08 ad Exp $");
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "pthread.h"
|
||||
#include "pthread_int.h"
|
||||
|
@ -155,6 +156,7 @@ __attribute ((noinline))
|
|||
static void
|
||||
pthread_spinlock_slow(pthread_spin_t *lock)
|
||||
{
|
||||
struct timespec ts;
|
||||
int count;
|
||||
#ifdef PTHREAD_SPIN_DEBUG
|
||||
pthread_t thread = pthread__self();
|
||||
|
@ -175,12 +177,14 @@ pthread_spinlock_slow(pthread_spin_t *lock)
|
|||
"(count %d)\n", thread, lock,
|
||||
thread->pt_spinlocks));
|
||||
thread->pt_spinlocks--;
|
||||
/* XXXLWP far from ideal */
|
||||
sched_yield();
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
nanosleep(&ts, NULL);
|
||||
thread->pt_spinlocks++;
|
||||
#else
|
||||
/* XXXLWP far from ideal */
|
||||
sched_yield();
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
} while (/*CONSTCOND*/ 1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue