summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2021-12-15 00:52:11 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-11-22 02:06:17 -0500
commit664b034b8403c8623eec0b7f1ce41d0aaede5edb (patch)
tree82cf5cba2aafee731e5d88147f249209e65389eb
parent39a91f60d958247cffdd6e10ac58030bc72ce464 (diff)
downloadhaskell-664b034b8403c8623eec0b7f1ce41d0aaede5edb.tar.gz
Replace EMPTY_{BLOCKED,SLEEPING}_QUEUE macros by function
These are the macros originaly from Scheduler.h, previously moved to IOManager.h, and now replaced with a single inline function anyPendingTimeoutsOrIO(). We can use a single function since the two macros were always checked together. Note that since anyPendingTimeoutsOrIO is defined for all IO manager cases, including threaded, we do not need to guard its use by cpp #if !defined(THREADED_RTS)
-rw-r--r--rts/IOManager.h40
-rw-r--r--rts/Schedule.c8
-rw-r--r--rts/Schedule.h8
3 files changed, 36 insertions, 20 deletions
diff --git a/rts/IOManager.h b/rts/IOManager.h
index 72bfac1fb0..80ef84b7c2 100644
--- a/rts/IOManager.h
+++ b/rts/IOManager.h
@@ -140,6 +140,14 @@ void appendToIOBlockedQueue(StgTSO *tso);
void insertIntoSleepingQueue(StgTSO *tso, LowResTime target);
#endif
+/* Check to see if there are any pending timeouts or I/O operations
+ * in progress with the I/O manager.
+ *
+ * This is used by the scheduler as part of deadlock-detection, and the
+ * "context switch as often as possible" test.
+ */
+INLINE_HEADER bool anyPendingTimeoutsOrIO(CapIOManager *iomgr);
+
/* Pedantic warning cleanliness
*/
@@ -163,12 +171,32 @@ void insertIntoSleepingQueue(StgTSO *tso, LowResTime target);
* -----------------------------------------------------------------------------
*/
-/* TODO: rename and replace these macros by inline functions
- * these have been moved here from Scheduler.h
- */
-#if !defined(THREADED_RTS)
-#define EMPTY_BLOCKED_QUEUE(cap) (emptyQueue(cap->iomgr->blocked_queue_hd))
-#define EMPTY_SLEEPING_QUEUE(cap) (emptyQueue(cap->iomgr->sleeping_queue))
+INLINE_HEADER bool anyPendingTimeoutsOrIO(CapIOManager *iomgr USED_IF_NOT_THREADS)
+{
+#if defined(THREADED_RTS)
+ /* For the purpose of the scheduler, the threaded I/O managers never have
+ pending I/O or timers. Of course in reality they do, but they're
+ managed via other primitives that the scheduler can see into (threads,
+ MVars and foreign blocking calls).
+ */
+ return false;
+#else
+#if defined(mingw32_HOST_OS)
+ /* The MIO I/O manager uses the blocked_queue, while the WinIO does not.
+ Note: the latter fact makes this test useless for the WinIO I/O manager,
+ and is the probable cause of the complication in the scheduler with
+ having to call awaitEvent in multiple places.
+
+ None of the Windows I/O managers use the sleeping_queue
+ */
+ return (iomgr->blocked_queue_hd != END_TSO_QUEUE);
+#else
+ /* The select() I/O manager uses the blocked_queue and the sleeping_queue.
+ */
+ return (iomgr->blocked_queue_hd != END_TSO_QUEUE)
+ || (iomgr->sleeping_queue != END_TSO_QUEUE);
+#endif
#endif
+}
#include "EndPrivate.h"
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 5d3789c31d..18ceae927b 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -911,7 +911,7 @@ scheduleCheckBlockedThreads(Capability *cap USED_IF_NOT_THREADS)
// sleeping_queue or the blocked_queue, so both queues will _always_ be
// empty and so awaitEvent will _never_ be called here for WinIO. This may
// explain why there is a second call to awaitEvent below for mingw32.
- if ( !EMPTY_BLOCKED_QUEUE(cap) || !EMPTY_SLEEPING_QUEUE(cap) )
+ if (anyPendingTimeoutsOrIO(cap->iomgr))
{
awaitEvent (emptyRunQueue(cap));
}
@@ -922,11 +922,7 @@ static bool
emptyThreadQueues(Capability *cap)
{
return emptyRunQueue(cap)
-#if !defined(THREADED_RTS)
- // TODO replace this by a test that deferrs to the active I/O manager
- && EMPTY_BLOCKED_QUEUE(cap) && EMPTY_SLEEPING_QUEUE(cap)
-#endif
- ;
+ && !anyPendingTimeoutsOrIO(cap->iomgr);
}
diff --git a/rts/Schedule.h b/rts/Schedule.h
index b0898b9a4c..b62e5a9762 100644
--- a/rts/Schedule.h
+++ b/rts/Schedule.h
@@ -146,14 +146,6 @@ peekRunQueue (Capability *cap)
void promoteInRunQueue (Capability *cap, StgTSO *tso);
-/* Check whether various thread queues are empty
- */
-INLINE_HEADER bool
-emptyQueue (StgTSO *q)
-{
- return (q == END_TSO_QUEUE);
-}
-
INLINE_HEADER bool
emptyRunQueue(Capability *cap)
{