23#define NFDBITS (sizeof (fd_mask) * 8)
24#define _howmany(x,y) (((x)+((y)-1))/(y))
70 syscall_log(
LOG_DEBUG,
"select(args=%p)\n", args);
72 struct aquila_select_args a;
74 if (copyin(&a, args,
sizeof(a))) {
79 fd_set *readfds = a.readfds;
80 fd_set *writefds = a.writefds;
81 fd_set *exceptfds = a.exceptfds;
90 fd_set want_read = {0}, want_write = {0}, out_read, out_write;
94 if ((readfds && copyin(&want_read, readfds,
sizeof(
fd_set))) ||
95 (writefds && copyin(&want_write, writefds,
sizeof(
fd_set))) ||
96 (a.timeout && copyin(&timeout, a.timeout,
sizeof(timeout))) ||
97 (sigmask && copyin(&mask, sigmask,
sizeof(mask)))) {
116 int count, timed_out = 0;
118#define FD_BIT(set, i) ((set).fds_bits[(i) / NFDBITS] & (1UL << ((i) % NFDBITS)))
119#define FD_ADD(set, i) ((set).fds_bits[(i) / NFDBITS] |= (1UL << ((i) % NFDBITS)))
126 for (
int i = 0; i < nfds; ++i) {
152 if (count || ns == 0 || timed_out) {
178 if ((readfds && copyout(readfds, &out_read,
sizeof(
fd_set))) ||
179 (writefds && copyout(writefds, &out_write,
sizeof(
fd_set))) ||
180 (exceptfds && copyout(exceptfds, &none,
sizeof(
fd_set)))) {
198long sys_poll(
struct pollfd *fds, nfds_t nfds,
int timeout_ms)
200 syscall_log(
LOG_DEBUG,
"poll(fds=%p, nfds=%d, timeout=%d)\n", fds, nfds, timeout_ms);
207 size_t size = nfds *
sizeof(
struct pollfd);
208 struct pollfd *kfds = nfds ?
kmalloc(size, &M_BUFFER, 0) :
NULL;
214 if (copyin(kfds, fds, size)) {
219 int64_t ns = timeout_ms < 0 ? -1 : (
int64_t) timeout_ms * 1000000;
221 int count, timed_out = 0;
227 for (nfds_t i = 0; i < nfds; ++i) {
228 struct pollfd *p = &kfds[i];
238 p->revents = POLLNVAL;
241 p->revents |= POLLIN;
244 p->revents |= POLLOUT;
247 count += !!p->revents;
256 if (count || ns == 0 || timed_out) {
272 if (count >= 0 && copyout(fds, kfds, size))
struct waitq * vfs_file_wait_queue(struct file *file, int write)
Finds the wait queue that a reader (or a writer) of an open file sleeps on until it can go on,...
int vfs_file_can_read(struct file *file, size_t size)
Says whether a read of an open file would go on without waiting, for poll() and select().
int vfs_file_can_write(struct file *file, size_t size)
Says whether a write to an open file would go on without waiting, for poll(), select() and non-blocki...
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
struct file * proc_fd_file(struct proc *proc, int fd)
Finds the open file a descriptor refers to.
int sched_wait(struct waitq *waitq, uint64_t until)
Puts the current thread to sleep on a wait queue until it is woken up, a signal ends the sleep,...
signed long long int int64_t
unsigned long long int uint64_t
fd_mask fds_bits[_howmany(FD_SETSIZE, NFDBITS)]
A file descriptor: the open file it refers to (fs/file.c, shared with the descriptors that dup() and ...
An open file (POSIX's "open file description", fs/file.c).
static int fd_ready(struct file *file, int write)
Returns whether file can be read (or written) without waiting.
long sys_select(struct aquila_select_args *args)
Implements select() and pselect(): waits until a descriptor of the sets can be read or written,...
static int fd_watch(struct file *file, int write)
Registers the wait queue that file's readers (or writers) sleep on, or NULL (any wakeup) if the file ...
long sys_poll(struct pollfd *fds, nfds_t nfds, int timeout_ms)
Implements poll(): waits until one of the descriptors can be read or written, or the timeout passes,...
static uint64_t poll_deadline(int64_t ns)
Returns the deadline of a timeout of ns ns: 0 for none (ns < 0).
static struct file * fd_peek(int fd)
Returns the open file a descriptor refers to, without holding it (as fd_file() does): it is only used...
uint64_t arch_rtime_ns(void)
Reads the monotonic clock, which starts at boot.
void poll_unregister(struct thread *thread)
Removes every registration of a thread, when it stops waiting (it was woken up, or it is going away).
int poll_register(struct waitq *waitq)
Registers a wait queue that the current thread, in select() or poll(), waits for: a wakeup of that qu...