X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FSelect.c;h=67ba589fc96ad2d8814344ef43b6901063ed3220;hb=b5b8ae092870b992b42123431be3cc2830af0e72;hp=5f43ec0874f0bc88e240938e69fb2d8a350748bd;hpb=5b4f5a6aa8f384573f0f11bc744d5637a1f3bc09;p=ghc-hetmet.git diff --git a/ghc/rts/Select.c b/ghc/rts/Select.c index 5f43ec0..67ba589 100644 --- a/ghc/rts/Select.c +++ b/ghc/rts/Select.c @@ -1,5 +1,4 @@ /* ----------------------------------------------------------------------------- - * $Id: Select.c,v 1.24 2003/02/21 05:34:16 sof Exp $ * * (c) The GHC Team 1995-2002 * @@ -7,6 +6,7 @@ * * ---------------------------------------------------------------------------*/ + /* we're outside the realms of POSIX here... */ /* #include "PosixSource.h" */ @@ -14,6 +14,7 @@ #include "Schedule.h" #include "RtsUtils.h" #include "RtsFlags.h" +#include "Timer.h" #include "Itimer.h" #include "Signals.h" #include "Capability.h" @@ -26,26 +27,16 @@ # include # endif -# ifdef mingw32_TARGET_OS -# include -# include "win32/AsyncIO.h" -# endif - #include #include -/* last timestamp */ -nat timestamp = 0; - -#ifdef RTS_SUPPORTS_THREADS -static rtsBool isWorkerBlockedInAwaitEvent = rtsFalse; -static rtsBool workerWakeupPending = rtsFalse; -#ifndef mingw32_TARGET_OS -static int workerWakeupPipe[2]; -static rtsBool workerWakeupInited = rtsFalse; -#endif +#ifdef HAVE_UNISTD_H +#include #endif +/* last timestamp */ +lnat timestamp = 0; + /* 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 * (it's actually 31 bits of microseconds), we can safely check @@ -58,7 +49,7 @@ static rtsBool workerWakeupInited = rtsFalse; * (idea due to Andy Gill). */ rtsBool -wakeUpSleepingThreads(nat ticks) +wakeUpSleepingThreads(lnat ticks) { StgTSO *tso; rtsBool flag = rtsFalse; @@ -69,7 +60,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; } @@ -95,10 +86,8 @@ awaitEvent(rtsBool wait) StgTSO *tso, *prev, *next; rtsBool ready; fd_set rfd,wfd; -#ifndef mingw32_TARGET_OS int numFound; int maxfd = -1; -#endif rtsBool select_succeeded = rtsTrue; rtsBool unblock_all = rtsFalse; struct timeval tv; @@ -108,11 +97,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 @@ -136,7 +125,6 @@ awaitEvent(rtsBool wait) min = 0x7ffffff; } -#ifndef mingw32_TARGET_OS /* * Collect all of the fd's that we're interested in */ @@ -168,34 +156,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; @@ -224,37 +184,19 @@ awaitEvent(rtsBool wait) unblock_all = rtsTrue; break; } else { - fprintf(stderr,"%d\n", errno); - fflush(stderr); perror("select"); barf("select failed"); } } -#else /* on mingwin */ -#ifdef RTS_SUPPORTS_THREADS - isWorkerBlockedInAwaitEvent = rtsTrue; -#endif - RELEASE_LOCK(&sched_mutex); - while (1) { - if (!awaitRequests(wait)) { - Sleep(0); /* don't busy wait */ - } -#endif /* mingw32_TARGET_OS */ - ACQUIRE_LOCK(&sched_mutex); -#ifdef RTS_SUPPORTS_THREADS - isWorkerBlockedInAwaitEvent = rtsFalse; -#endif -#ifndef mingw32_TARGET_OS /* 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 @@ -275,24 +217,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. */ @@ -313,7 +239,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); @@ -334,42 +260,5 @@ awaitEvent(rtsBool wait) } } -#if defined(RTS_SUPPORTS_THREADS) && !defined(mingw32_TARGET_OS) - // 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() -{ -#ifndef mingw32_TARGET_OS - 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; - } -#else - // The Win32 implementation currently uses a polling loop, - // so there is no need to explicitly wake it -#endif -} - -#endif