From: Alan Cox Date: Tue, 30 Dec 2014 23:13:34 +0000 (+0000) Subject: select: further filling out .. not there yet X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=b77747716dfb7a734e9e45e2c0f7a37c4f5c614d;p=FUZIX.git select: further filling out .. not there yet Pipe bugs need fixing before we can really do select --- diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 47dbf871..ade811de 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -673,7 +673,16 @@ CODE2 void exec_or_die(void); CODE2 extern void seladdwait(struct selmap *s); CODE2 extern void selrmwait(struct selmap *s); CODE2 extern void selwake(struct selmap *s); +#ifdef CONFIG_SELECT +CODE2 extern int selwait_inode(inoptr i, uint8_t smask, uint8_t setit); +CODE2 extern void selwake_inode(inoptr i, uint16_t mask); +CODE2 extern void selwake_pipe(inoptr i, uint16_t mask); CODE2 extern int _select(void); +#else +#define selwait_inode(i,smask,setit) do {} while(0) +#define selwake_inode(i,smask,setit) do {} while(0) +#define selwake_pipe(i,smask,setit) do {} while(0) +#endif /* swap.c */ extern ptptr swapproc; diff --git a/Kernel/select.c b/Kernel/select.c index 2c92ffdc..5353c222 100644 --- a/Kernel/select.c +++ b/Kernel/select.c @@ -44,31 +44,31 @@ void selwake(struct selmap *s) } /* Set our select bits on the inode */ -int selwait_inode(inoptr i, uint8_t mask, uint8_t setit) { +int selwait_inode(inoptr i, uint8_t smask, uint8_t setit) { struct selmap *s = (struct selmap *)(&i->c_node.i_addr[17]); uint8_t bit = udata.u_ptab - ptab; uint8_t mask = 1 << (bit & 7); uint8_t bset = bit & setit; bit >>= 3; - if (mask & SELECT_IN) { + if (smask & SELECT_IN) { s->map[mask] &= ~bit; s->map[mask] |= bset; } s++; - if (mask & SELECT_OUT) { + if (smask & SELECT_OUT) { s->map[mask] &= ~bit; s->map[mask] |= bset; } s++; - if (mask & SELECT_EX) { + if (smask & SELECT_EX) { s->map[mask] &= ~bit; s->map[mask] |= bset; } } /* Wake an inode for select */ -int selwake_inode(inoptr i, uint16_t mask) { +void selwake_inode(inoptr i, uint16_t mask) { struct selmap *s = (struct selmap *)(&i->c_node.i_addr[17]); if (mask & SELECT_IN) selwake(s); @@ -80,6 +80,33 @@ int selwake_inode(inoptr i, uint16_t mask) { selwake(s); } +static int pipesel_begin(inoptr i, uint8_t bits) +{ + uint16_t mask = 0; + pipesel++; + /* Data or EOF */ + if (i->c_node.i_size || !i->c_refs) + mask |= SELECT_IN; + /* Enough room to be worth waking - keep wakeup rate down */ + if (i->c_node.i_size < 8 * BLKSIZE) + mask |= SELECT_OUT; + selwait_inode(i, bits, 1); + return mask & bits; +} + +static int pipesel_end(inoptr i) +{ + pipesel--; + /* Clear out wait masks */ + selwait(i, SELECT_IN|SELECT_OUT|SELECT_EX, 0); +} + +void selwake_pipe(inoptr i, uint16_t mask) +{ + if (pipesel) + selwake_inode(i); +} + #define nfd (uint16_t)udata.u_argn #define base (uint16_t)udata.u_argn1 @@ -103,6 +130,14 @@ int _select(void) m = 1; for (i = 0; i < nfd; i++) { if (sum & m) { + if (in & m) + n = SELECT_IN; + else + n = 0; + if (out & m) + n |= SELECT_OUT; + if (ex & m) + n |= SELECT_EX; ino = getinode(i); if (ino == NULLINODE) return -1; @@ -115,14 +150,15 @@ int _select(void) inr |= m; break; case F_PIPE: - /* TODO */ - break; + n = pipesel_begin(ino, n); + goto setbits; case F_CDEV: /* If unsupported we report the device as read/write ready */ if (d_ioctl(ino->c_node.i_addr[0], SELECT_BEGIN, &n) == -1) { udata.u_error = 0; n = SELECT_IN|SELECT_OUT; } +setbits: /* Set the outputs */ if (n & SELECT_IN) inr |= m; @@ -143,6 +179,8 @@ int _select(void) } while (!sumo && udata.p_tab->p_timeout != 1); + udata.p_tab->p_timeout = 0; + /* Return the values to user space */ uputw(inr, base); uputw(outr, base + 4); @@ -154,9 +192,14 @@ int _select(void) for (i = 0; i < nfd; i++) { if (sum & m) { ino = getinode(i); - if (getmode(ino) == F_CDEV) - d_ioctl(ino->c_node.i_addr[0], SELECT_END, NULL); - /* FIXME - pipe */ + switch(getmode(ino)) + { + case F_CDEV: + d_ioctl(ino->c_node.i_addr[0], SELECT_END, NULL); + break; + case F_PIPE: + pipesel_end(ino); + } } m <<= 1; }