summaryrefslogtreecommitdiff
path: root/rts/posix
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2020-12-29 17:39:19 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-11-22 02:06:17 -0500
commitced9acdbe757331d8d0046df30a06e61b05dd204 (patch)
tree52f6796b25bf23c5eeaa0b88e4b794b09d30386a /rts/posix
parent5cf709c541a46a17ef2e36d589ba13d949d058e1 (diff)
downloadhaskell-ced9acdbe757331d8d0046df30a06e61b05dd204.tar.gz
Move {blocked,sleeping}_queue from scheduler global vars to CapIOManager
The blocked_queue_{hd,tl} and the sleeping_queue are currently cooperatively managed between the scheduler and (some but not all of) the non-threaded I/O manager implementations. They lived as global vars with the scheduler, but are poked by I/O primops and the I/O manager backends. This patch is a step on the path towards making the management of I/O or timer blocking belong to the I/O managers and not the scheduler. Specifically, this patch moves the {blocked,sleeping}_queue from being global vars in the scheduler to being members of the CapIOManager struct within each Capability. They are not yet exclusively used by the I/O managers: they are still poked from a couple other places, notably in the scheduler before calling awaitEvent.
Diffstat (limited to 'rts/posix')
-rw-r--r--rts/posix/Select.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/rts/posix/Select.c b/rts/posix/Select.c
index 2f9f95728c..f02fd63981 100644
--- a/rts/posix/Select.c
+++ b/rts/posix/Select.c
@@ -98,12 +98,12 @@ static bool wakeUpSleepingThreads (LowResTime now)
StgTSO *tso;
bool flag = false;
- while (sleeping_queue != END_TSO_QUEUE) {
- tso = sleeping_queue;
+ while (MainCapability.iomgr->sleeping_queue != END_TSO_QUEUE) {
+ tso = MainCapability.iomgr->sleeping_queue;
if (((long)now - (long)tso->block_info.target) < 0) {
break;
}
- sleeping_queue = tso->_link;
+ MainCapability.iomgr->sleeping_queue = tso->_link;
tso->why_blocked = NotBlocked;
tso->_link = END_TSO_QUEUE;
IF_DEBUG(scheduler, debugBelch("Waking up sleeping thread %"
@@ -253,7 +253,9 @@ awaitEvent(bool wait)
FD_ZERO(&rfd);
FD_ZERO(&wfd);
- for(tso = blocked_queue_hd; tso != END_TSO_QUEUE; tso = next) {
+ for(tso = MainCapability.iomgr->blocked_queue_hd;
+ tso != END_TSO_QUEUE;
+ tso = next) {
next = tso->_link;
/* On older FreeBSDs, FD_SETSIZE is unsigned. Cast it to signed int
@@ -298,7 +300,7 @@ awaitEvent(bool wait)
tv.tv_sec = 0;
tv.tv_usec = 0;
ptv = &tv;
- } else if (sleeping_queue != END_TSO_QUEUE) {
+ } else if (MainCapability.iomgr->sleeping_queue != END_TSO_QUEUE) {
/* SUSv2 allows implementations to have an implementation defined
* maximum timeout for select(2). The standard requires
* implementations to silently truncate values exceeding this maximum
@@ -317,7 +319,10 @@ awaitEvent(bool wait)
*/
const time_t max_seconds = 2678400; // 31 * 24 * 60 * 60
- Time min = LowResTimeToTime(sleeping_queue->block_info.target - now);
+ Time min = LowResTimeToTime(
+ MainCapability.iomgr->sleeping_queue->block_info.target
+ - now
+ );
tv.tv_sec = TimeToSeconds(min);
if (tv.tv_sec < max_seconds) {
tv.tv_usec = TimeToUS(min) % 1000000;
@@ -385,7 +390,9 @@ awaitEvent(bool wait)
* traversed blocked TSOs. As a result you
* can't use functions accessing 'blocked_queue_hd'.
*/
- for(tso = blocked_queue_hd; tso != END_TSO_QUEUE; tso = next) {
+ for(tso = MainCapability.iomgr->blocked_queue_hd;
+ tso != END_TSO_QUEUE;
+ tso = next) {
next = tso->_link;
int fd;
enum FdState fd_state = RTS_FD_IS_BLOCKING;
@@ -435,7 +442,7 @@ awaitEvent(bool wait)
break;
case RTS_FD_IS_BLOCKING:
if (prev == NULL)
- blocked_queue_hd = tso;
+ MainCapability.iomgr->blocked_queue_hd = tso;
else
setTSOLink(&MainCapability, prev, tso);
prev = tso;
@@ -444,10 +451,11 @@ awaitEvent(bool wait)
}
if (prev == NULL)
- blocked_queue_hd = blocked_queue_tl = END_TSO_QUEUE;
+ MainCapability.iomgr->blocked_queue_hd =
+ MainCapability.iomgr->blocked_queue_tl = END_TSO_QUEUE;
else {
prev->_link = END_TSO_QUEUE;
- blocked_queue_tl = prev;
+ MainCapability.iomgr->blocked_queue_tl = prev;
}
}