From c2f26f36b87ffe4824fc3d62449340285d80ed56 Mon Sep 17 00:00:00 2001 From: Duncan Coutts <duncan@well-typed.com> Date: Tue, 29 Nov 2022 23:18:41 +0000 Subject: [PATCH] Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. --- rts/IOManager.c | 41 ++++++++++++++++++++++++++++++++++++++++- rts/IOManager.h | 7 +++++++ rts/PrimOps.cmm | 26 ++++---------------------- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/rts/IOManager.c b/rts/IOManager.c index 4e3f3b06f4f4..3e6761b219a9 100644 --- a/rts/IOManager.c +++ b/rts/IOManager.c @@ -458,7 +458,44 @@ setIOManagerControlFd(uint32_t cap_no USED_IF_THREADS, int fd USED_IF_THREADS) { } #endif -#if !defined(THREADED_RTS) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" + +void syncIOWaitReady(Capability *cap USED_IF_NOT_THREADS, + StgTSO *tso USED_IF_NOT_THREADS, + IOReadOrWrite rw USED_IF_NOT_THREADS, + HsInt fd USED_IF_NOT_THREADS) +{ + ASSERT(tso->why_blocked == NotBlocked); + switch (iomgr_type) { +#if defined(IOMGR_ENABLED_SELECT) + case IO_MANAGER_SELECT: + { + StgWord why_blocked = rw == IORead ? BlockedOnRead : BlockedOnWrite; + tso->block_info.fd = fd; + RELEASE_STORE(&tso->why_blocked, why_blocked); + appendToIOBlockedQueue(cap, tso); + break; + } +#endif +#if defined(IOMGR_ENABLED_WIN32_LEGACY) + case IO_MANAGER_WIN32_LEGACY: + { + StgWord why_blocked = rw == IORead ? BlockedOnRead : BlockedOnWrite; + tso->block_info.fd = fd; + RELEASE_STORE(&tso->why_blocked, why_blocked); + appendToIOBlockedQueue(cap, tso); + break; + } +#endif + default: + barf("waitRead# / waitWrite# not available for current I/O manager"); + } +} +#pragma GCC diagnostic pop + + +#if defined(IOMGR_ENABLED_SELECT) || defined(IOMGR_ENABLED_WIN32_LEGACY) void appendToIOBlockedQueue(Capability *cap, StgTSO *tso) { CapIOManager *iomgr = cap->iomgr; @@ -470,7 +507,9 @@ void appendToIOBlockedQueue(Capability *cap, StgTSO *tso) } iomgr->blocked_queue_tl = tso; } +#endif +#if defined(IOMGR_ENABLED_SELECT) void insertIntoSleepingQueue(Capability *cap, StgTSO *tso, LowResTime target) { CapIOManager *iomgr = cap->iomgr; diff --git a/rts/IOManager.h b/rts/IOManager.h index fb25d1f7e40a..df9d1b1d6f82 100644 --- a/rts/IOManager.h +++ b/rts/IOManager.h @@ -272,6 +272,13 @@ void wakeupIOManager(void); void markCapabilityIOManager(evac_fn evac, void *user, CapIOManager *iomgr); +/* Several code paths are almost identical between read and write paths. In + * such cases we use a shared code path with an enum to say which we're doing. + */ +typedef enum { IORead, IOWrite } IOReadOrWrite; + +void syncIOWaitReady(Capability *cap, StgTSO *tso, IOReadOrWrite rw, HsInt fd); + #if !defined(THREADED_RTS) /* Add a thread to the end of the queue of threads blocked on I/O. * diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index 9f9bfdaf7a13..46c6c926b1e4 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -2548,34 +2548,16 @@ stg_whereFromzh (P_ clos, W_ buf) stg_waitReadzh ( W_ fd ) { -#if defined(THREADED_RTS) - ccall barf("waitRead# on threaded RTS") never returns; -#else - - ASSERT(StgTSO_why_blocked(CurrentTSO) == NotBlocked::I32); - StgTSO_block_info(CurrentTSO) = fd; - %release StgTSO_why_blocked(CurrentTSO) = BlockedOnRead::I32; - // No locking - we're not going to use this interface in the - // threaded RTS anyway. - ccall appendToIOBlockedQueue(MyCapability() "ptr", CurrentTSO "ptr"); + ccall syncIOWaitReady(MyCapability() "ptr", CurrentTSO "ptr", + /* IORead */ 0::I32, fd); jump stg_block_noregs(); -#endif } stg_waitWritezh ( W_ fd ) { -#if defined(THREADED_RTS) - ccall barf("waitWrite# on threaded RTS") never returns; -#else - - ASSERT(StgTSO_why_blocked(CurrentTSO) == NotBlocked::I32); - StgTSO_block_info(CurrentTSO) = fd; - %release StgTSO_why_blocked(CurrentTSO) = BlockedOnWrite::I32; - // No locking - we're not going to use this interface in the - // threaded RTS anyway. - ccall appendToIOBlockedQueue(MyCapability() "ptr", CurrentTSO "ptr"); + ccall syncIOWaitReady(MyCapability() "ptr", CurrentTSO "ptr", + /* IOWrite */ 1::I32, fd); jump stg_block_noregs(); -#endif } stg_delayzh ( W_ us_delay ) -- GitLab