X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FSelect.c;h=3cec3a9afc9b36e48d7fccb4b6208d40bbcf949e;hb=9f3fe695451887ade350abc1a2b2a72c75adc402;hp=73aad1a2a6c5d6e14e071e35f194c8b6043ed1dc;hpb=384d5bcf83b6e7ee103fca364ca1ab6ef831834a;p=ghc-hetmet.git diff --git a/ghc/rts/Select.c b/ghc/rts/Select.c index 73aad1a..3cec3a9 100644 --- a/ghc/rts/Select.c +++ b/ghc/rts/Select.c @@ -1,5 +1,4 @@ /* ----------------------------------------------------------------------------- - * $Id: Select.c,v 1.26 2003/02/22 06:13:41 sof Exp $ * * (c) The GHC Team 1995-2002 * @@ -7,14 +6,10 @@ * * ---------------------------------------------------------------------------*/ - /* we're outside the realms of POSIX here... */ /* #include "PosixSource.h" */ #include "Rts.h" -#ifndef mingw32_TARGET_OS -/* to the end */ - #include "Schedule.h" #include "RtsUtils.h" #include "RtsFlags.h" @@ -34,15 +29,17 @@ #include #include +#ifdef HAVE_UNISTD_H +#include +#endif + /* last timestamp */ -nat timestamp = 0; +lnat timestamp = 0; -#ifdef RTS_SUPPORTS_THREADS -static rtsBool isWorkerBlockedInAwaitEvent = rtsFalse; -static rtsBool workerWakeupPending = rtsFalse; -static int workerWakeupPipe[2]; -static rtsBool workerWakeupInited = rtsFalse; -#endif +#if !defined(RTS_SUPPORTS_THREADS) +/* + * The threaded RTS uses an IO-manager thread in Haskell instead (see GHC.Conc) + */ /* There's a clever trick here to avoid problems when the time wraps * around. Since our maximum delay is smaller than 31 bits of ticks @@ -56,7 +53,7 @@ static rtsBool workerWakeupInited = rtsFalse; * (idea due to Andy Gill). */ rtsBool -wakeUpSleepingThreads(nat ticks) +wakeUpSleepingThreads(lnat ticks) { StgTSO *tso; rtsBool flag = rtsFalse; @@ -67,7 +64,7 @@ wakeUpSleepingThreads(nat ticks) sleeping_queue = tso->link; tso->why_blocked = NotBlocked; tso->link = END_TSO_QUEUE; - IF_DEBUG(scheduler,belch("Waking up sleeping thread %d\n", tso->id)); + IF_DEBUG(scheduler,debugBelch("Waking up sleeping thread %d\n", tso->id)); PUSH_ON_RUN_QUEUE(tso); flag = rtsTrue; } @@ -104,11 +101,11 @@ awaitEvent(rtsBool wait) tv.tv_usec = 0; IF_DEBUG(scheduler, - belch("scheduler: checking for threads blocked on I/O"); + debugBelch("scheduler: checking for threads blocked on I/O"); if (wait) { - belch(" (waiting)"); + debugBelch(" (waiting)"); } - belch("\n"); + debugBelch("\n"); ); /* loop until we've woken up some threads. This loop is needed @@ -163,34 +160,6 @@ awaitEvent(rtsBool wait) } } -#ifdef RTS_SUPPORTS_THREADS - if(!workerWakeupInited) { - pipe(workerWakeupPipe); - workerWakeupInited = rtsTrue; - } - FD_SET(workerWakeupPipe[0], &rfd); - maxfd = workerWakeupPipe[0] > maxfd ? workerWakeupPipe[0] : maxfd; -#endif - - /* Release the scheduler lock while we do the poll. - * this means that someone might muck with the blocked_queue - * while we do this, but it shouldn't matter: - * - * - another task might poll for I/O and remove one - * or more threads from the blocked_queue. - * - more I/O threads may be added to blocked_queue. - * - more delayed threads may be added to blocked_queue. We'll - * just subtract delta from their delays after the poll. - * - * I believe none of these cases lead to trouble --SDM. - */ - -#ifdef RTS_SUPPORTS_THREADS - isWorkerBlockedInAwaitEvent = rtsTrue; - workerWakeupPending = rtsFalse; -#endif - RELEASE_LOCK(&sched_mutex); - /* Check for any interesting events */ tv.tv_sec = min / 1000000; @@ -219,28 +188,22 @@ awaitEvent(rtsBool wait) unblock_all = rtsTrue; break; } else { - fprintf(stderr,"%d\n", errno); - fflush(stderr); perror("select"); barf("select failed"); } } - ACQUIRE_LOCK(&sched_mutex); -#ifdef RTS_SUPPORTS_THREADS - isWorkerBlockedInAwaitEvent = rtsFalse; -#endif /* We got a signal; could be one of ours. If so, we need * to start up the signal handler straight away, otherwise * we could block for a long time before the signal is * serviced. */ +#if defined(RTS_USER_SIGNALS) if (signals_pending()) { - RELEASE_LOCK(&sched_mutex); /* ToDo: kill */ startSignalHandlers(); - ACQUIRE_LOCK(&sched_mutex); return; /* still hold the lock */ } +#endif /* we were interrupted, return to the scheduler immediately. */ @@ -258,24 +221,8 @@ awaitEvent(rtsBool wait) if (run_queue_hd != END_TSO_QUEUE) { return; /* still hold the lock */ } - -#ifdef RTS_SUPPORTS_THREADS - /* If another worker thread wants to take over, - * return to the scheduler - */ - if (needToYieldToReturningWorker()) { - return; /* still hold the lock */ - } -#endif - -#ifdef RTS_SUPPORTS_THREADS - isWorkerBlockedInAwaitEvent = rtsTrue; -#endif - RELEASE_LOCK(&sched_mutex); } - ACQUIRE_LOCK(&sched_mutex); - /* Step through the waiting queue, unblocking every thread that now has * a file descriptor in a ready state. */ @@ -296,7 +243,7 @@ awaitEvent(rtsBool wait) } if (ready) { - IF_DEBUG(scheduler,belch("Waking up blocked thread %d\n", tso->id)); + IF_DEBUG(scheduler,debugBelch("Waking up blocked thread %d\n", tso->id)); tso->why_blocked = NotBlocked; tso->link = END_TSO_QUEUE; PUSH_ON_RUN_QUEUE(tso); @@ -317,37 +264,7 @@ awaitEvent(rtsBool wait) } } -#if defined(RTS_SUPPORTS_THREADS) - // if we were woken up by wakeBlockedWorkerThread, - // read the dummy byte from the pipe - if(select_succeeded && FD_ISSET(workerWakeupPipe[0], &rfd)) { - unsigned char dummy; - wait = rtsFalse; - read(workerWakeupPipe[0],&dummy,1); - } -#endif } while (wait && !interrupted && run_queue_hd == END_TSO_QUEUE); } - -#ifdef RTS_SUPPORTS_THREADS -/* wakeBlockedWorkerThread - * - * If a worker thread is currently blocked within awaitEvent, - * wake it. - * Must be called with sched_mutex held. - */ -void -wakeBlockedWorkerThread() -{ - if(isWorkerBlockedInAwaitEvent && !workerWakeupPending) { - unsigned char dummy = 42; // Any value will do here - - // write something so that select() wakes up - write(workerWakeupPipe[1],&dummy,1); - workerWakeupPending = rtsTrue; - } -} -#endif - -#endif /* !mingw_TARGET_OS */ +#endif /* RTS_SUPPORTS_THREADS */