Skip to content

Commit 918b610

Browse files
committed
ATRONIX: Fix the poor performance in network writing
The poor performance is hit when there is only one active port with a big packet (> 64k bytes) to write. The network driver will split the packet into 32k chunks, and only send the first chunk before returning RD_PEND. When N_wait checks for signals from this port, it sees no signal (write is not done yet), and thus the wait time is doubled, and OS_Wait is called. In OS_Wait, default Poll_Default is called, which goes through all pending requests for the device. Because the packet is so big, after a second "write", the packet is still not sent completely, and the status remains the same: DR_PEND, which causes Poll_Default mistakenly thinks the device is inactive, and then OS_Wait starts waiting with the doubled wait time. The wait time could get doubled further until its max if the packet is quite big. The fix is in two folds: 1. Introduce a new flag RRF_ACTIVE, to mark the request as active in case that partial data is written 2. Modify Poll_Default funcntion to check RRF_ACTIVE in addition to the current DR_DONE/DR_ERROR. So when the data is partial written, Poll_Default will return "TRUE", which causes OS_Wait to return immediately, no matter how long the "wait time" is. (cherry picked from commit 4b5faab)
1 parent 02c203c commit 918b610

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

src/include/reb-device.h

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ enum {
9393
RRF_PENDING, // Request is attached to pending list
9494
RRF_ALLOC, // Request is allocated, not a temp on stack
9595
RRF_WIDE, // Wide char IO
96+
RRF_ACTIVE, // Port is active, even no new events yet
9697
};
9798

9899
// REBOL Device Errors:

src/os/dev-net.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ static REBOOL Nonblocking_Mode(SOCKET sock)
461461
Signal_Device(sock, EVT_WROTE);
462462
return DR_DONE;
463463
}
464+
SET_FLAG(sock->flags, RRF_ACTIVE); /* notify OS_WAIT of activity */
464465
return DR_PEND;
465466
}
466467
// if (result < 0) ...
@@ -613,7 +614,6 @@ static REBOOL Nonblocking_Mode(SOCKET sock)
613614
return DR_PEND;
614615
}
615616

616-
617617
/***********************************************************************
618618
**
619619
** Command Dispatch Table (RDC_ enum order)

src/os/host-device.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,10 @@ static int Poll_Default(REBDEV *dev)
103103
for (req = *prior; req; req = *prior) {
104104

105105
// Call command again:
106-
if (req->command < RDC_MAX)
106+
if (req->command < RDC_MAX) {
107+
CLR_FLAG(req->flags, RRF_ACTIVE);
107108
result = dev->commands[req->command](req);
108-
else {
109+
} else {
109110
result = -1; // invalid command, remove it
110111
req->error = ((REBCNT)-1);
111112
}
@@ -116,8 +117,12 @@ static int Poll_Default(REBDEV *dev)
116117
req->next = 0;
117118
CLR_FLAG(req->flags, RRF_PENDING);
118119
change = TRUE;
120+
} else {
121+
prior = &req->next;
122+
if (GET_FLAG(req->flags, RRF_ACTIVE)) {
123+
change = TRUE;
124+
}
119125
}
120-
else prior = &req->next;
121126
}
122127

123128
return change;

0 commit comments

Comments
 (0)