Do a similar tuneup on pthread_cond_signal() and
pthread_cond_broadcast(): use double-checked locking to avoid pthread__self() and pthread_spinlock() when signaling or broadcasting on a condition variable with no waiters.
This commit is contained in:
parent
6cca91fc86
commit
69367db47f
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pthread_cond.c,v 1.3 2003/01/27 21:01:01 nathanw Exp $ */
|
/* $NetBSD: pthread_cond.c,v 1.4 2003/01/31 04:26:50 nathanw Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -267,21 +267,23 @@ pthread_cond_signal(pthread_cond_t *cond)
|
||||||
#endif
|
#endif
|
||||||
PTHREADD_ADD(PTHREADD_COND_SIGNAL);
|
PTHREADD_ADD(PTHREADD_COND_SIGNAL);
|
||||||
|
|
||||||
self = pthread__self();
|
|
||||||
SDPRINTF(("(cond signal %p) Signaling %p\n",
|
SDPRINTF(("(cond signal %p) Signaling %p\n",
|
||||||
self, cond));
|
pthread__self(), cond));
|
||||||
|
|
||||||
pthread_spinlock(self, &cond->ptc_lock);
|
if (!PTQ_EMPTY(&cond->ptc_waiters)) {
|
||||||
signaled = PTQ_FIRST(&cond->ptc_waiters);
|
self = pthread__self();
|
||||||
if (signaled != NULL)
|
pthread_spinlock(self, &cond->ptc_lock);
|
||||||
PTQ_REMOVE(&cond->ptc_waiters, signaled, pt_sleep);
|
signaled = PTQ_FIRST(&cond->ptc_waiters);
|
||||||
|
if (signaled != NULL)
|
||||||
|
PTQ_REMOVE(&cond->ptc_waiters, signaled, pt_sleep);
|
||||||
#ifdef ERRORCHECK
|
#ifdef ERRORCHECK
|
||||||
if (PTQ_EMPTY(&cond->ptc_waiters))
|
if (PTQ_EMPTY(&cond->ptc_waiters))
|
||||||
cond->ptc_mutex = NULL;
|
cond->ptc_mutex = NULL;
|
||||||
#endif
|
#endif
|
||||||
if (signaled != NULL)
|
if (signaled != NULL)
|
||||||
pthread__sched(self, signaled);
|
pthread__sched(self, signaled);
|
||||||
pthread_spinunlock(self, &cond->ptc_lock);
|
pthread_spinunlock(self, &cond->ptc_lock);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -298,19 +300,21 @@ pthread_cond_broadcast(pthread_cond_t *cond)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PTHREADD_ADD(PTHREADD_COND_BROADCAST);
|
PTHREADD_ADD(PTHREADD_COND_BROADCAST);
|
||||||
self = pthread__self();
|
|
||||||
SDPRINTF(("(cond signal %p) Broadcasting %p\n",
|
SDPRINTF(("(cond signal %p) Broadcasting %p\n",
|
||||||
self, cond));
|
pthread__self(), cond));
|
||||||
|
|
||||||
pthread_spinlock(self, &cond->ptc_lock);
|
if (!PTQ_EMPTY(&cond->ptc_waiters)) {
|
||||||
blockedq = cond->ptc_waiters;
|
self = pthread__self();
|
||||||
PTQ_INIT(&cond->ptc_waiters);
|
pthread_spinlock(self, &cond->ptc_lock);
|
||||||
|
blockedq = cond->ptc_waiters;
|
||||||
|
PTQ_INIT(&cond->ptc_waiters);
|
||||||
#ifdef ERRORCHECK
|
#ifdef ERRORCHECK
|
||||||
cond->ptc_mutex = NULL;
|
cond->ptc_mutex = NULL;
|
||||||
#endif
|
#endif
|
||||||
PTQ_FOREACH(signaled, &blockedq, pt_sleep)
|
PTQ_FOREACH(signaled, &blockedq, pt_sleep)
|
||||||
pthread__sched(self, signaled);
|
pthread__sched(self, signaled);
|
||||||
pthread_spinunlock(self, &cond->ptc_lock);
|
pthread_spinunlock(self, &cond->ptc_lock);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue