From: Tulio A M Mendes Date: Mon, 16 Feb 2026 15:49:22 +0000 (-0300) Subject: feat: EPOLLET edge-triggered epoll mode with smoke test (81/81) X-Git-Url: https://projects.tadryanom.me/docs/static/git-logo.png?a=commitdiff_plain;h=ac3563e3b8c34a7d196b5c14109d1a936c02b7c6;p=AdrOS.git feat: EPOLLET edge-triggered epoll mode with smoke test (81/81) --- diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index df15109..cd9ad83 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -1055,6 +1055,7 @@ struct epoll_interest { int fd; uint32_t events; uint64_t data; + uint32_t last_revents; }; struct epoll_instance { @@ -1136,6 +1137,7 @@ static int syscall_epoll_ctl_impl(int epfd, int op, int fd, ep->items[ep->count].fd = fd; ep->items[ep->count].events = ev.events; ep->items[ep->count].data = ev.data; + ep->items[ep->count].last_revents = 0; ep->count++; return 0; } @@ -1147,6 +1149,7 @@ static int syscall_epoll_ctl_impl(int epfd, int op, int fd, if (copy_from_user(&ev, user_event, sizeof(ev)) < 0) return -EFAULT; ep->items[idx].events = ev.events; ep->items[idx].data = ev.data; + ep->items[idx].last_revents = 0; return 0; } @@ -1212,9 +1215,19 @@ static int syscall_epoll_wait_impl(int epfd, struct epoll_event* user_events, if (vfs_rev & VFS_POLL_HUP) revents |= EPOLLHUP; if (revents) { - out[ready].events = revents; - out[ready].data = ep->items[i].data; - ready++; + int report = 1; + if (ep->items[i].events & EPOLLET) { + uint32_t new_bits = revents & ~ep->items[i].last_revents; + if (!new_bits) report = 0; + } + ep->items[i].last_revents = revents; + if (report) { + out[ready].events = revents; + out[ready].data = ep->items[i].data; + ready++; + } + } else { + ep->items[i].last_revents = 0; } } diff --git a/tests/smoke_test.exp b/tests/smoke_test.exp index 2be35e9..a7f712b 100755 --- a/tests/smoke_test.exp +++ b/tests/smoke_test.exp @@ -100,6 +100,7 @@ set tests { {"poll regfile" "\\[init\\] poll regfile OK"} {"hard link" "\\[init\\] hard link OK"} {"epoll" "\\[init\\] epoll OK"} + {"epollet" "\\[init\\] epollet OK"} {"inotify" "\\[init\\] inotify OK"} {"aio" "\\[init\\] aio OK"} {"nanosleep" "\\[init\\] nanosleep OK"} diff --git a/user/init.c b/user/init.c index 6f5fa59..53f6de8 100644 --- a/user/init.c +++ b/user/init.c @@ -184,8 +184,9 @@ struct pollfd { }; enum { - POLLIN = 0x0001, + POLLIN = 0x0001, POLLOUT = 0x0004, + EPOLLET = (1U << 31), }; enum { @@ -3256,6 +3257,66 @@ void _start(void) { sys_write(1, "[init] epoll OK\n", (uint32_t)(sizeof("[init] epoll OK\n") - 1)); } + // C22b: EPOLLET edge-triggered mode + { + int epfd = sys_epoll_create(1); + if (epfd < 0) { + sys_write(1, "[init] epollet create failed\n", (uint32_t)(sizeof("[init] epollet create failed\n") - 1)); + sys_exit(1); + } + + int fds[2]; + if (sys_pipe(fds) < 0) { + sys_write(1, "[init] epollet pipe failed\n", (uint32_t)(sizeof("[init] epollet pipe failed\n") - 1)); + sys_exit(1); + } + + struct { uint32_t events; uint32_t data; } ev; + ev.events = POLLIN | EPOLLET; + ev.data = 42; + if (sys_epoll_ctl(epfd, 1, fds[0], &ev) < 0) { + sys_write(1, "[init] epollet ctl failed\n", (uint32_t)(sizeof("[init] epollet ctl failed\n") - 1)); + sys_exit(1); + } + + (void)sys_write(fds[1], "X", 1); + + struct { uint32_t events; uint32_t data; } out; + int n = sys_epoll_wait(epfd, &out, 1, 0); + if (n != 1 || !(out.events & POLLIN)) { + sys_write(1, "[init] epollet first wait failed\n", (uint32_t)(sizeof("[init] epollet first wait failed\n") - 1)); + sys_exit(1); + } + + n = sys_epoll_wait(epfd, &out, 1, 0); + if (n != 0) { + sys_write(1, "[init] epollet second wait should be 0\n", (uint32_t)(sizeof("[init] epollet second wait should be 0\n") - 1)); + sys_exit(1); + } + + char tmp; + (void)sys_read(fds[0], &tmp, 1); + + n = sys_epoll_wait(epfd, &out, 1, 0); + if (n != 0) { + sys_write(1, "[init] epollet post-drain should be 0\n", (uint32_t)(sizeof("[init] epollet post-drain should be 0\n") - 1)); + sys_exit(1); + } + + (void)sys_write(fds[1], "Y", 1); + + n = sys_epoll_wait(epfd, &out, 1, 0); + if (n != 1 || !(out.events & POLLIN)) { + sys_write(1, "[init] epollet re-arm failed\n", (uint32_t)(sizeof("[init] epollet re-arm failed\n") - 1)); + sys_exit(1); + } + + (void)sys_close(fds[0]); + (void)sys_close(fds[1]); + (void)sys_close(epfd); + sys_write(1, "[init] epollet OK\n", (uint32_t)(sizeof("[init] epollet OK\n") - 1)); + } + // C23: inotify_init/add_watch/rm_watch smoke { int ifd = sys_inotify_init();