/* ---------------------------------------------------------------------------
- * $Id: Schedule.c,v 1.184 2003/12/18 12:24:59 simonmar Exp $
+ * $Id: Schedule.c,v 1.188 2004/02/26 16:19:32 simonmar Exp $
*
* (c) The GHC Team, 1998-2003
*
Mutex sched_mutex = INIT_MUTEX_VAR;
Mutex term_mutex = INIT_MUTEX_VAR;
-/*
- * A heavyweight solution to the problem of protecting
- * the thread_id from concurrent update.
- */
-Mutex thread_id_mutex = INIT_MUTEX_VAR;
-
#endif /* RTS_SUPPORTS_THREADS */
#if defined(PAR)
// Always start with the compiled code evaluator
tso->what_next = ThreadRunGHC;
- /* tso->id needs to be unique. For now we use a heavyweight mutex to
- * protect the increment operation on next_thread_id.
- * In future, we could use an atomic increment instead.
- */
- ACQUIRE_LOCK(&thread_id_mutex);
tso->id = next_thread_id++;
- RELEASE_LOCK(&thread_id_mutex);
-
tso->why_blocked = NotBlocked;
tso->blocked_exceptions = NULL;
RELEASE_LOCK(&sched_mutex);
}
+#if defined(RTS_SUPPORTS_THREADS)
+static Condition *bound_cond_cache = NULL;
+#endif
+
SchedulerStatus
scheduleWaitThread(StgTSO* tso, /*[out]*/HaskellObj* ret,
Capability *initialCapability)
m->ret = ret;
m->stat = NoStatus;
#if defined(RTS_SUPPORTS_THREADS)
- initCondition(&m->bound_thread_cond);
+ // Allocating a new condition for each thread is expensive, so we
+ // cache one. This is a pretty feeble hack, but it helps speed up
+ // consecutive call-ins quite a bit.
+ if (bound_cond_cache != NULL) {
+ m->bound_thread_cond = *bound_cond_cache;
+ bound_cond_cache = NULL;
+ } else {
+ initCondition(&m->bound_thread_cond);
+ }
#endif
/* Put the thread on the main-threads list prior to scheduling the TSO.
* the scheduler. */
initMutex(&sched_mutex);
initMutex(&term_mutex);
- initMutex(&thread_id_mutex);
-
- initCondition(&thread_ready_cond);
#endif
#if defined(RTS_SUPPORTS_THREADS)
stat = m->stat;
#if defined(RTS_SUPPORTS_THREADS)
- closeCondition(&m->bound_thread_cond);
+ // Free the condition variable, returning it to the cache if possible.
+ if (bound_cond_cache == NULL) {
+ *bound_cond_cache = m->bound_thread_cond;
+ } else {
+ closeCondition(&m->bound_thread_cond);
+ }
#endif
IF_DEBUG(scheduler, sched_belch("main thread (%d) finished", m->tso->id));