Skip to content

Commit c6a3342

Browse files
authored
Simpify passing of timeout to select() syscall. NFC (#25968)
Rather than using a pointer to memory, simply pass the number of milliseconds to block for, using the same convensions poll(): ``` -1: Block forever 0: No blocking >0: Block for up to N milliseconds. ``` This is already the interface used by the inner `stream.stream_ops.poll` call so this saves on conversion as well as reading from memory.
1 parent 7401ae4 commit c6a3342

File tree

6 files changed

+26
-28
lines changed

6 files changed

+26
-28
lines changed

src/lib/libsigs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ sigs = {
229229
__handle_stack_overflow__sig: 'vp',
230230
__pthread_create_js__sig: 'ipppp',
231231
__resumeException__sig: 'vp',
232-
__syscall__newselect__sig: 'iipppp',
232+
__syscall__newselect__sig: 'iipppj',
233233
__syscall_accept4__sig: 'iippiii',
234234
__syscall_bind__sig: 'iippiii',
235235
__syscall_chdir__sig: 'ip',

src/lib/libsyscall.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,8 @@ var SyscallsLibrary = {
542542
FS.chdir(stream.path);
543543
return 0;
544544
},
545-
__syscall__newselect: (nfds, readfds, writefds, exceptfds, timeout) => {
545+
__syscall__newselect__i53abi: true,
546+
__syscall__newselect: (nfds, readfds, writefds, exceptfds, timeoutInMillis) => {
546547
// readfds are supported,
547548
// writefds checks socket open status
548549
// exceptfds are supported, although on web, such exceptional conditions never arise in web sockets
@@ -584,18 +585,11 @@ var SyscallsLibrary = {
584585
var flags = SYSCALLS.DEFAULT_POLLMASK;
585586

586587
if (stream.stream_ops.poll) {
587-
var timeoutInMillis = -1;
588-
if (timeout) {
589-
// select(2) is declared to accept "struct timeval { time_t tv_sec; suseconds_t tv_usec; }".
590-
// However, musl passes the two values to the syscall as an array of long values.
591-
// Note that sizeof(time_t) != sizeof(long) in wasm32. The former is 8, while the latter is 4.
592-
// This means using "C_STRUCTS.timeval.tv_usec" leads to a wrong offset.
593-
// So, instead, we use POINTER_SIZE.
594-
var tv_sec = (readfds ? {{{ makeGetValue('timeout', 0, 'i32') }}} : 0),
595-
tv_usec = (readfds ? {{{ makeGetValue('timeout', POINTER_SIZE, 'i32') }}} : 0);
596-
timeoutInMillis = (tv_sec + tv_usec / 1000000) * 1000;
597-
}
598588
flags = stream.stream_ops.poll(stream, timeoutInMillis);
589+
} else {
590+
#if ASSERTIONS
591+
if (timeoutInMillis != 0) warnOnce('non-zero select() timeout not supported: ' + timeoutInMillis)
592+
#endif
599593
}
600594

601595
if ((flags & {{{ cDefs.POLLIN }}}) && check(fd, srcReadLow, srcReadHigh, mask)) {
@@ -638,6 +632,9 @@ var SyscallsLibrary = {
638632
return 0; // we can't do anything synchronously; the in-memory FS is already synced to
639633
},
640634
__syscall_poll: (fds, nfds, timeout) => {
635+
#if ASSERTIONS
636+
if (timeout != 0) warnOnce('non-zero poll() timeout not supported: ' + timeout)
637+
#endif
641638
var nonzero = 0;
642639
for (var i = 0; i < nfds; i++) {
643640
var pollfd = fds + {{{ C_STRUCTS.pollfd.__size__ }}} * i;

system/lib/libc/musl/arch/emscripten/syscall_arch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ int __syscall_uname(intptr_t buf);
4141
int __syscall_mprotect(size_t addr, size_t len, int prot);
4242
int __syscall_getpgid(int pid);
4343
int __syscall_fchdir(int fd);
44-
int __syscall__newselect(int nfds, intptr_t readfds, intptr_t writefds, intptr_t exceptfds, intptr_t timeout);
44+
int __syscall__newselect(int nfds, intptr_t readfds, intptr_t writefds, intptr_t exceptfds, int64_t timeout);
4545
int __syscall_msync(intptr_t addr, size_t len, int flags);
4646
int __syscall_getsid(int pid);
4747
int __syscall_fdatasync(int fd);

system/lib/libc/musl/src/select/select.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict
1515
const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
1616

1717
if (s<0 || us<0) return __syscall_ret(-EINVAL);
18+
#ifdef __EMSCRIPTEN__
19+
uint64_t millis = tv ? s * 1000 + (us / 1000) : -1;
20+
return syscall_cp(SYS_select, n, rfds, wfds, efds, millis);
21+
#else
1822
if (us/1000000 > max_time - s) {
1923
s = max_time;
2024
us = 999999;
@@ -24,7 +28,6 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict
2428
us %= 1000000;
2529
ns = us*1000;
2630
}
27-
2831
#ifdef SYS_pselect6_time64
2932
int r = -ENOSYS;
3033
if (SYS_pselect6 == SYS_pselect6_time64 || !IS32BIT(s))
@@ -42,4 +45,5 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict
4245
return syscall_cp(SYS_pselect6, n, rfds, wfds, efds,
4346
tv ? ((long[]){s, ns}) : 0, ((syscall_arg_t[]){ 0, _NSIG/8 }));
4447
#endif
48+
#endif
4549
}

system/lib/wasmfs/syscalls.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,14 +1772,13 @@ int __syscall__newselect(int nfds,
17721772
intptr_t _readfds,
17731773
intptr_t _writefds,
17741774
intptr_t _exceptfds,
1775-
intptr_t _timeout) {
1775+
int64_t timeout) {
17761776
// Implement select in terms of `poll()`
17771777

17781778
// Part 1: convert select arguments into poll arguments
17791779
fd_set* readfds = (fd_set*)_readfds;
17801780
fd_set* writefds = (fd_set*)_writefds;
17811781
fd_set* exceptfds = (fd_set*)_exceptfds;
1782-
timeval* timeout = (timeval*)_timeout;
17831782

17841783
int n = 0;
17851784
struct pollfd* fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd));
@@ -1800,14 +1799,12 @@ int __syscall__newselect(int nfds,
18001799
}
18011800
}
18021801

1803-
// __syscall_poll currently ignores timeout but we calculate it here for
1804-
// completeness.
1805-
int timeout_ms = -1; // Infinite
1806-
if (timeout) {
1807-
timeout_ms = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
1808-
}
1809-
1810-
int rtn = __syscall_poll((intptr_t)fds, n, timeout_ms);
1802+
// emscripten's __syscall__newselect already takes a timeout that is
1803+
// compatible with __syscall_poll:
1804+
// -1: Block forever
1805+
// 0: Never block
1806+
// >0: Block for up to N milliseconds.
1807+
int rtn = __syscall_poll((intptr_t)fds, n, timeout);
18111808
if (rtn < 0) {
18121809
free(fds);
18131810
return -1;

test/codesize/test_codesize_hello_dylink_all.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"a.out.js": 245673,
3-
"a.out.nodebug.wasm": 573748,
4-
"total": 819421,
2+
"a.out.js": 245617,
3+
"a.out.nodebug.wasm": 573657,
4+
"total": 819274,
55
"sent": [
66
"IMG_Init",
77
"IMG_Load",

0 commit comments

Comments
 (0)