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:
ad 2007-09-07 00:07:54 +00:00
parent 513227e941
commit c67dc640cd
1 changed files with 10 additions and 6 deletions

View File

@ -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);
}