[Git][ghc/ghc][wip/dcoutts/io-manager-tidy] Only use FdWakeup for Poll I/O manager when HAVE_PREEMPTION
Duncan Coutts pushed to branch wip/dcoutts/io-manager-tidy at Glasgow Haskell Compiler / GHC Commits: 213060ce by Duncan Coutts at 2026-06-22T14:53:38+01:00 Only use FdWakeup for Poll I/O manager when HAVE_PREEMPTION This is to allow it to build and work on wasm, but without support for interruptIOManager. - - - - - 3 changed files: - rts/IOManagerInternals.h - rts/posix/FdWakeup.h - rts/posix/Poll.c Changes: ===================================== rts/IOManagerInternals.h ===================================== @@ -47,9 +47,11 @@ struct _CapIOManager { #endif #if defined(IOMGR_ENABLED_SELECT) || defined(IOMGR_ENABLED_POLL) +#if defined(HAVE_PREEMPTION) /* FDs for waking up the I/O manager when it is blocked waiting */ int interrupt_fd_r, interrupt_fd_w; #endif +#endif #if defined(IOMGR_ENABLED_POLL) /* AIOP and timeout collections shared by several I/O manager impls */ ===================================== rts/posix/FdWakeup.h ===================================== @@ -29,12 +29,14 @@ #include "BeginPrivate.h" +#if defined(HAVE_PREEMPTION) void newFdWakeup(int *fd_r, int *fd_w); void closeFdWakeup(int fd_r, int fd_w); /* This is safe to use from a signal handler */ void sendFdWakeup(int fd_w); void collectFdWakeup(int fd_r); +#endif #include "EndPrivate.h" ===================================== rts/posix/Poll.c ===================================== @@ -142,13 +142,20 @@ void initCapabilityIOManagerPoll(CapIOManager *iomgr) initClosureTable(&iomgr->aiop_table, ClosureTableCompact); iomgr->timeout_queue = emptyTimeoutQueue(); +#if defined(HAVE_PREEMPTION) newFdWakeup(&iomgr->interrupt_fd_r, &iomgr->interrupt_fd_w); +#endif iomgr->full_poll_table = stgMallocBytes(sizeof(struct pollfd) /* size 1 */, "initCapabilityIOManagerPoll"); iomgr->full_poll_table[0] = (struct pollfd) { +#if defined(HAVE_PREEMPTION) .fd = iomgr->interrupt_fd_r, .events = POLLIN, +#else + .fd = -1, // unused + .events = 0, // unused +#endif .revents = 0 }; iomgr->aiop_poll_table = iomgr->full_poll_table+1; /* hence empty */ @@ -158,7 +165,9 @@ void initCapabilityIOManagerPoll(CapIOManager *iomgr) void freeCapabilityIOManagerPoll(CapIOManager *iomgr) { stgFree(iomgr->full_poll_table); +#if defined(HAVE_PREEMPTION) closeFdWakeup(iomgr->interrupt_fd_r, iomgr->interrupt_fd_w); +#endif } @@ -326,7 +335,8 @@ static bool processIOCompletions(CapIOManager *iomgr, int ncompletions) debugTrace(DEBUG_iomanager, "processIOCompletions(ncompletions = %d)", ncompletions); - bool interrupt; + bool interrupt = false; +#if defined(HAVE_PREEMPTION) /* If the interrupt_fd_r is ready, collect it */ if (iomgr->full_poll_table[0].revents) { ASSERT(iomgr->full_poll_table[0].fd == iomgr->interrupt_fd_r); @@ -334,9 +344,8 @@ static bool processIOCompletions(CapIOManager *iomgr, int ncompletions) ncompletions--; interrupt = true; debugTrace(DEBUG_iomanager, "Received interrupt in poll I/O manager"); - } else { - interrupt = false; } +#endif struct pollfd *aiop_poll_table = iomgr->aiop_poll_table; int n = ncompletions; @@ -407,18 +416,26 @@ void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr) nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1; +#if defined(HAVE_PREEMPTION) + /* the full_poll_table includes interrupt_fd_r */ + struct pollfd *poll_table = iomgr->full_poll_table; +#else + /* the aiop_poll_table does not include interrupt_fd_r */ + struct pollfd *poll_table = iomgr->aiop_poll_table; +#endif + /* Poll for I/O readiness, without waiting. */ #if defined(HAVE_DECL_PPOLL) && HAVE_DECL_PPOLL == 1 /* We could use poll here, since we use no timeout, but for consistency we use the same syscall as at the other call site. */ struct timespec tv = (struct timespec) { .tv_sec = 0, .tv_nsec = 0 }; - int res = ppoll(iomgr->full_poll_table, nfds, &tv, NULL); + int res = ppoll(poll_table, nfds, &tv, NULL); debugTrace(DEBUG_iomanager, "ppoll(nfds = %d, timeout.sec = 0, timeout.nsec = 0) = %d", nfds, res); #else - int res = poll(iomgr->full_poll_table, nfds, 0); + int res = poll(poll_table, nfds, 0); debugTrace(DEBUG_iomanager, "poll(nfds = %d, timeout_ms = 0) = %d", @@ -471,6 +488,14 @@ bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr) */ bool wait = emptyRunQueue(iomgr->cap); +#if defined(HAVE_PREEMPTION) + /* the full_poll_table includes interrupt_fd_r */ + struct pollfd *poll_table = iomgr->full_poll_table; +#else + /* the aiop_poll_table does not include interrupt_fd_r */ + struct pollfd *poll_table = iomgr->aiop_poll_table; +#endif + /* Decide if we are going to wait if no I/O is ready, either: * poll only, wait indefinitely, or wait until a timeout. */ @@ -484,7 +509,7 @@ bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr) /* Check for I/O readiness, possibly waiting. */ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1; #if defined(HAVE_DECL_PPOLL) && HAVE_DECL_PPOLL == 1 - int res = ppoll(iomgr->full_poll_table, nfds, timeout_ns, NULL); + int res = ppoll(poll_table, nfds, timeout_ns, NULL); debugTrace(DEBUG_iomanager, "ppoll(nfds = %d, timeout.sec = %d, timeout.nsec = %d) = %d", @@ -492,7 +517,7 @@ bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr) timeout_ns == NULL ? 0 : timeout_ns->tv_nsec, res); #else - int res = poll(iomgr->full_poll_table, nfds, timeout_ms); + int res = poll(poll_table, nfds, timeout_ms); debugTrace(DEBUG_iomanager, "poll(nfds = %d, timeout_ms = %d) = %d", @@ -565,7 +590,9 @@ static void reportPollError(int res, nfds_t nfds) void interruptIOManagerPoll(CapIOManager *iomgr) { +#if defined(HAVE_PREEMPTION) sendFdWakeup(iomgr->interrupt_fd_w); +#endif } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/213060cec8eda703147e07fa46764d6b... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/213060cec8eda703147e07fa46764d6b... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Duncan Coutts (@dcoutts)