From: Alan Cox Date: Thu, 14 Dec 2017 13:42:16 +0000 (+0000) Subject: kernel: introduce a u_done counter set to 0 in rwsetup X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=097af6e4746756f56d502e642813cf417b9d4952;p=FUZIX.git kernel: introduce a u_done counter set to 0 in rwsetup We then use this to clean up psleep_flags_io and some other code. This also saves us a few bytes --- diff --git a/Kernel/dev/net/net_z80pack.c b/Kernel/dev/net/net_z80pack.c index 7e76240a..4dd2a8d6 100644 --- a/Kernel/dev/net/net_z80pack.c +++ b/Kernel/dev/net/net_z80pack.c @@ -214,7 +214,6 @@ void net_close(struct socket *s) */ arg_t net_read(struct socket *s, uint8_t flag) { - usize_t n = 0; struct sockdata *sd = s->s_priv; irqflags_t irq; uint8_t st; @@ -248,20 +247,20 @@ arg_t net_read(struct socket *s, uint8_t flag) break; } uputc(data, udata.u_base++); - n++; - if (n < udata.u_count) + udata.u_done++; + if (udata.u_done < udata.u_count) continue; } - if (n) + if (udata.u_done) break; s->s_iflag &= ~SI_DATA; - if (psleep_flags_io(&s->s_iflag, flag, &n)) { + if (psleep_flags_io(&s->s_iflag, flag)) { irqrestore(irq); return -1; } } - if (n) - return n; + if (udata.u_done) + return udata.u_done; if (st & 0x80) { err_xlate(s); return -1; @@ -275,7 +274,6 @@ arg_t net_read(struct socket *s, uint8_t flag) */ arg_t net_write(struct socket * s, uint8_t flag) { - usize_t n = 0; uint8_t p = 0; struct sockdata *sd = s->s_priv; irqflags_t irq; @@ -298,10 +296,10 @@ arg_t net_write(struct socket * s, uint8_t flag) break; /* Good status after a write means byte ok */ - n += p; - if (n == udata.u_count) { + udata.u_done += p; + if (udata.u_done == udata.u_count) { irqrestore(irq); - return n; + return udata.u_done; } /* Can we send more bytes ? */ p = 0; @@ -315,7 +313,7 @@ arg_t net_write(struct socket * s, uint8_t flag) continue; } s->s_iflag |= SI_THROTTLE; - if (psleep_flags_io(&s->s_iflag, flag, &n)) { + if (psleep_flags_io(&s->s_iflag, flag)) { irqrestore(irq); return n; } @@ -323,10 +321,10 @@ arg_t net_write(struct socket * s, uint8_t flag) } /* It broke mummy ! */ irqrestore(irq); - if (n) { + if (udata.u_done) { s->s_error = udata.u_error; udata.u_error = 0; - return n; + return udata.u_done; } err_xlate(s); if (udata.u_error == EPIPE) diff --git a/Kernel/dev/z80pack/devlpr.c b/Kernel/dev/z80pack/devlpr.c index e292cd6e..5e90eb36 100644 --- a/Kernel/dev/z80pack/devlpr.c +++ b/Kernel/dev/z80pack/devlpr.c @@ -18,36 +18,36 @@ int lpr_close(uint8_t minor) return 0; } -static int iopoll(int sofar) +static uint8_t iopoll(void) { /* Ought to be a core helper for this lot ? */ if (need_reschedule()) _sched_yield(); if (chksigs()) { - if (sofar) - return sofar; - udata.u_error = EINTR; - return -1; + if (!udata.u_done) { + udata.u_error = EINTR; + udata.u_done = (usize_t)-1; + } + return 1; } return 0; } int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag) { - int c = udata.u_count; char *p = udata.u_base; minor; rawflag; flag; // shut up compiler - while(c) { + while(udata.u_done < udata.u_count) { /* Note; on real hardware it might well be necessary to busy wait a bit just to get acceptable performance */ while (lpstat != 0xFF) { - int n; - if (n = iopoll(p - udata.u_base)) - return n; + if (iopoll()) + return udata.u_done; } /* FIXME: tidy up ugetc and sysio checks globally */ lpdata = ugetc(p++); + udata.u_done++; } - return (-1); + return udata.u_done; } diff --git a/Kernel/devio.c b/Kernel/devio.c index 9ad7a6c5..79719a05 100644 --- a/Kernel/devio.c +++ b/Kernel/devio.c @@ -474,19 +474,19 @@ bool uninsq(struct s_queue *q, unsigned char *cp) Miscellaneous helpers **********************************************************************/ -int psleep_flags_io(void *p, unsigned char flags, usize_t *n) +int psleep_flags_io(void *p, unsigned char flags) { if (flags & O_NDELAY) { - if (!*n) { - *n = (usize_t)-1; + if (!udata.u_done) { + udata.u_done = (usize_t)-1; udata.u_error = EAGAIN; } return -1; } psleep(p); if (chksigs()) { - if (!*n) { - *n = (usize_t)-1; + if (!udata.u_done) { + udata.u_done = (usize_t)-1; udata.u_error = EINTR; } return -1; @@ -496,8 +496,16 @@ int psleep_flags_io(void *p, unsigned char flags, usize_t *n) int psleep_flags(void *p, unsigned char flags) { - usize_t dummy = 0; - return psleep_flags_io(p, flags, &dummy); + if (flags & O_NDELAY) { + udata.u_error = EAGAIN; + return -1; + } + psleep(p); + if (chksigs()) { + udata.u_error = EINTR; + return -1; + } + return 0; } void kputs(const char *p) diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index a3f62dd7..e6d0b6be 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -21,6 +21,10 @@ From UZI by Doug Braun and UZI280 by Stefan Nitschke. #define NULL (void *)0 #endif +#ifndef regptr +#define regptr +#endif + #define min(a,b) ( (a) < (b) ? (a) : (b) ) #define max(a,b) ( (a) > (b) ? (a) : (b) ) #define aligndown(v,a) (uint8_t*)((intptr_t)(v) & ~((a)-1)) @@ -40,8 +44,8 @@ From UZI by Doug Braun and UZI280 by Stefan Nitschke. #include "level2.h" #else -#define jobcontrol_in(x,y,z) 0 -#define jobcontrol_out(x,y,z) 0 +#define jobcontrol_in(x,y) 0 +#define jobcontrol_out(x,y) 0 #define jobcontrol_ioctl(x,y,z) 0 #define limit_exceeded(x,y) (0) @@ -516,6 +520,7 @@ typedef struct u_data { uint16_t u_blkoff; /* Offset in block */ usize_t u_nblock; /* Number of blocks */ uint8_t *u_dptr; /* Address for I/O */ + usize_t u_done; /* Counter for driver methods */ #ifdef CONFIG_LEVEL_2 uint16_t u_groups[NGROUP]; /* Group list */ @@ -820,7 +825,7 @@ extern bool insq(struct s_queue *q, unsigned char c); extern bool remq(struct s_queue *q, unsigned char *cp); extern void clrq(struct s_queue *q); extern bool uninsq(struct s_queue *q, unsigned char *cp); -extern int psleep_flags_io(void *event, unsigned char flags, usize_t *n); +extern int psleep_flags_io(void *event, unsigned char flags); extern int psleep_flags(void *event, unsigned char flags); extern int nxio_open(uint8_t minor, uint16_t flag); extern int no_open(uint8_t minor, uint16_t flag); diff --git a/Kernel/inode.c b/Kernel/inode.c index 86ea99ab..23219895 100644 --- a/Kernel/inode.c +++ b/Kernel/inode.c @@ -293,6 +293,7 @@ inoptr rwsetup(bool is_read, uint8_t * flag) udata.u_sysio = false; /* I/O to user data space */ udata.u_base = (unsigned char *) udata.u_argn1; /* buf */ udata.u_count = (susize_t) udata.u_argn2; /* nbytes */ + udata.u_done = 0; /* bytes done so far */ if ((ino = getinode(udata.u_argn)) == NULLINODE) { /* kprintf("[WRS: rwsetup(): getinode(%x) fails]", udata.u_argn); */ diff --git a/Kernel/level2.c b/Kernel/level2.c index d27c4e87..bfe30716 100644 --- a/Kernel/level2.c +++ b/Kernel/level2.c @@ -79,28 +79,28 @@ static uint8_t jobop(uint8_t minor, uint8_t sig, struct tty *t, uint8_t ign) } /* For input readign with SIGTTIN blocked gets you an EIO */ -uint8_t jobcontrol_in(uint8_t minor, struct tty *t, usize_t *nread) +uint8_t jobcontrol_in(uint8_t minor, struct tty *t) { if (!jobop(minor, SIGTTIN, t, 0)) return 0; - if (*nread == 0) { + if (udata.u_done == 0) { udata.u_error = EINTR; - *nread = (usize_t)-1; + udata.u_done = (usize_t)-1; } return 1; } /* For output ignored stop is taken to mean as write anyway */ -uint8_t jobcontrol_out(uint8_t minor, struct tty *t, usize_t *written) +uint8_t jobcontrol_out(uint8_t minor, struct tty *t) { if (!(t->termios.c_lflag & TOSTOP)) return 0; if (!jobop(minor, SIGTTOU, t, 1)) return 0; - if (*written == 0) { + if (udata.u_done == 0) { udata.u_error = EINTR; - *written = (usize_t)-1; + udata.u_done = (usize_t)-1; } return 1; } diff --git a/Kernel/tty.c b/Kernel/tty.c index 24b9b6fe..9afb868f 100644 --- a/Kernel/tty.c +++ b/Kernel/tty.c @@ -34,7 +34,6 @@ static void tty_selwake(uint8_t minor, uint16_t event) int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) { - usize_t nread; unsigned char c; struct s_queue *q; struct tty *t; @@ -44,12 +43,12 @@ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) q = &ttyinq[minor]; t = &ttydata[minor]; - nread = 0; - while (nread < udata.u_count) { + + while (udata.u_done < udata.u_count) { for (;;) { #ifdef CONFIG_LEVEL_2 - if (jobcontrol_in(minor, t, &nread)) - return nread; + if (jobcontrol_in(minor, t)) + return udata.u_done; #endif if ((t->flag & TTYF_DEAD) && (!q->q_count)) goto dead; @@ -63,25 +62,25 @@ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) if (!(t->termios.c_lflag & ICANON)) { uint8_t n = t->termios.c_cc[VTIME]; - if ((nread || !n) && nread >= t->termios.c_cc[VMIN]) + if ((udata.u_done || !n) && udata.u_done >= t->termios.c_cc[VMIN]) goto out; if (n) udata.u_ptab->p_timeout = n + 1; } - if (psleep_flags_io(q, flag, &nread)) + if (psleep_flags_io(q, flag)) goto out; /* timer expired */ if (udata.u_ptab->p_timeout == 1) goto out; } - ++nread; + ++udata.u_done; /* return according to mode */ if (t->termios.c_lflag & ICANON) { - if (nread == 1 && (c == t->termios.c_cc[VEOF])) { + if (udata.u_done == 1 && (c == t->termios.c_cc[VEOF])) { /* ^D */ - nread = 0; + udata.u_done = 0; break; } if (c == '\n' || c == t->termios.c_cc[VEOL]) @@ -92,7 +91,7 @@ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) } out: wakeup(&q->q_count); - return nread; + return udata.u_done; dead: udata.u_error = ENXIO; @@ -102,18 +101,17 @@ dead: int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) { struct tty *t; - usize_t written = 0; uint8_t c; used(rawflag); t = &ttydata[minor]; - while (udata.u_count-- != 0) { + while (udata.u_done != udata.u_count) { for (;;) { /* Wait on the ^S/^Q flag */ #ifdef CONFIG_LEVEL_2 - if (jobcontrol_out(minor, t, &written)) - return written; + if (jobcontrol_out(minor, t)) + return udata.u_done; #endif if (t->flag & TTYF_DEAD) { udata.u_error = ENXIO; @@ -121,8 +119,8 @@ int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) } if (!(t->flag & TTYF_STOP)) break; - if (psleep_flags_io(&t->flag, flag, &written)) - return written; + if (psleep_flags_io(&t->flag, flag)) + return udata.u_done; } if (!(t->flag & TTYF_DISCARD)) { if (udata.u_sysio) @@ -141,9 +139,9 @@ int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) break; } ++udata.u_base; - ++written; + ++udata.u_done; } - return written; + return udata.u_done; }