Skip to content

Commit

Permalink
kernel: introduce a u_done counter set to 0 in rwsetup
Browse files Browse the repository at this point in the history
We then use this to clean up psleep_flags_io and some other code. This also
saves us a few bytes
  • Loading branch information
Alan Cox committed Dec 14, 2017
1 parent e539203 commit 097af6e
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 60 deletions.
26 changes: 12 additions & 14 deletions Kernel/dev/net/net_z80pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -315,18 +313,18 @@ 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;
}
di();
}
/* 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)
Expand Down
22 changes: 11 additions & 11 deletions Kernel/dev/z80pack/devlpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
22 changes: 15 additions & 7 deletions Kernel/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
11 changes: 8 additions & 3 deletions Kernel/include/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions Kernel/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); */
Expand Down
12 changes: 6 additions & 6 deletions Kernel/level2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
36 changes: 17 additions & 19 deletions Kernel/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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])
Expand All @@ -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;
Expand All @@ -102,27 +101,26 @@ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
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;
return -1;
}
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)
Expand All @@ -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;
}


Expand Down

0 comments on commit 097af6e

Please sign in to comment.