From 98055e0a161627b2f2cdc6c7bc620473ed30d526 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 22 Feb 2016 21:46:10 +0000 Subject: [PATCH] getmode: make getmode 8bit We do a lot of compares and switches with getmode and the switches in particular get expensive on an 8 bit processor. Instead shift stuff and force it all into 8bit space. This saves us a couple of hundred bytes even though SDCC still writes very poor code for 8bit switches Alan --- Kernel/filesys.c | 12 +++++++----- Kernel/include/kernel.h | 5 ++++- Kernel/inode.c | 28 ++++++++++++++-------------- Kernel/select.c | 14 +++++++------- Kernel/syscall_fs2.c | 4 ++-- Kernel/syscall_fs3.c | 8 ++++---- Kernel/syscall_other.c | 8 ++++---- 7 files changed, 42 insertions(+), 37 deletions(-) diff --git a/Kernel/filesys.c b/Kernel/filesys.c index 49f3b6bb..a5d8e017 100644 --- a/Kernel/filesys.c +++ b/Kernel/filesys.c @@ -77,7 +77,7 @@ inoptr kn_open(char *namep, inoptr *parent) } i_deref(wd); wd = ninode; - if(getmode(wd) != F_DIR){ + if(getmode(wd) != MODE_R(F_DIR)){ udata.u_error = ENOTDIR; goto nodir; } @@ -877,7 +877,7 @@ blkno_t bmap(inoptr ip, blkno_t bn, int rwflg) int sh; uint16_t dev; - if(getmode(ip) == F_BDEV) + if(getmode(ip) == MODE_R(F_BDEV)) return(bn); dev = ip->c_dev; @@ -1052,9 +1052,11 @@ void setftime(inoptr ino, uint8_t flag) } -uint16_t getmode(inoptr ino) +uint8_t getmode(inoptr ino) { - return(ino->c_node.i_mode & F_MASK); + /* Shifting by 9 (past permissions might be more logical but + 8 happens to be cheap */ + return (ino->c_node.i_mode & F_MASK) >> 8; } @@ -1137,7 +1139,7 @@ void magic(inoptr ino) * syscall banks. */ arg_t unlinki(inoptr ino, inoptr pino, char *fname) { - if (getmode(ino) == F_DIR) { + if (getmode(ino) == MODE_R(F_DIR)) { udata.u_error = EISDIR; return -1; } diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 21f56dbc..94983e44 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -213,6 +213,9 @@ struct hd_geometry { #define F_MASK 0170000 +/* So we can do all our getmode comparisons in 8bit to help the compilers out */ +#define MODE_R(x) ((uint8_t)((x) >> 8)) + #define major(x) ((x) >> 8) #define minor(x) ((x) & 0xFF) @@ -765,7 +768,7 @@ extern bool super(void); extern bool esuper(void); extern uint8_t getperm(inoptr ino); extern void setftime(inoptr ino, uint8_t flag); -extern uint16_t getmode(inoptr ino); +extern uint8_t getmode(inoptr ino); extern struct mount *fs_tab_get(uint16_t dev); /* returns true on failure, false on success */ extern bool fmount(uint16_t dev, inoptr ino, uint16_t flags); diff --git a/Kernel/inode.c b/Kernel/inode.c index 5c5fa2f8..1c590db9 100644 --- a/Kernel/inode.c +++ b/Kernel/inode.c @@ -23,8 +23,8 @@ void readi(inoptr ino, uint8_t flag) dev = ino->c_dev; ispipe = false; switch (getmode(ino)) { - case F_DIR: - case F_REG: + case MODE_R(F_DIR): + case MODE_R(F_REG): /* See if end of file will limit read */ if (ino->c_node.i_size <= udata.u_offset) @@ -36,12 +36,12 @@ void readi(inoptr ino, uint8_t flag) toread = udata.u_count; goto loop; - case F_SOCK: + case MODE_R(F_SOCK): #ifdef CONFIG_NET udata.u_count = sock_read(ino, flag); break; #endif - case F_PIPE: + case MODE_R(F_PIPE): ispipe = true; while (ino->c_node.i_size == 0 && !(flag & O_NDELAY)) { if (ino->c_refs == 1) /* No writers */ @@ -57,7 +57,7 @@ void readi(inoptr ino, uint8_t flag) } goto loop; - case F_BDEV: + case MODE_R(F_BDEV): toread = udata.u_count; dev = *(ino->c_node.i_addr); @@ -111,7 +111,7 @@ void readi(inoptr ino, uint8_t flag) } break; - case F_CDEV: + case MODE_R(F_CDEV): udata.u_count = cdread(ino->c_node.i_addr[0], flag); if (udata.u_count != (usize_t)-1) @@ -138,20 +138,20 @@ void writei(inoptr ino, uint8_t flag) switch (getmode(ino)) { - case F_BDEV: + case MODE_R(F_BDEV): dev = *(ino->c_node.i_addr); - case F_DIR: - case F_REG: + case MODE_R(F_DIR): + case MODE_R(F_REG): ispipe = false; towrite = udata.u_count; goto loop; #ifdef CONFIG_NET - case F_SOCK: + case MODE_R(F_SOCK): udata.u_count = sock_write(ino, flag); break; #endif - case F_PIPE: + case MODE_R(F_PIPE): ispipe = true; /* FIXME: this will hang if you ever write > 16 * BLKSIZE in one go - needs merging into the loop */ @@ -217,7 +217,7 @@ void writei(inoptr ino, uint8_t flag) } break; - case F_CDEV: + case MODE_R(F_CDEV): udata.u_count = cdwrite(ino->c_node.i_addr[0], flag); if (udata.u_count != -1) @@ -242,7 +242,7 @@ int16_t doclose(uint8_t uindex) if (of_tab[oftindex].o_refs == 1) { if (isdevice(ino)) d_close((int) (ino->c_node.i_addr[0])); - if (getmode(ino) == F_REG && O_ACCMODE(of_tab[oftindex].o_access)) + if (getmode(ino) == MODE_R(F_REG) && O_ACCMODE(of_tab[oftindex].o_access)) flush_dev = ino->c_dev; #ifdef CONFIG_NET if (issocket(ino)) @@ -282,7 +282,7 @@ inoptr rwsetup(bool is_read, uint8_t * flag) } setftime(ino, is_read ? A_TIME : (A_TIME | M_TIME | C_TIME)); - if (getmode(ino) == F_REG && is_read == 0 + if (getmode(ino) == MODE_R(F_REG) && is_read == 0 && (oftp->o_access & O_APPEND)) oftp->o_ptr = ino->c_node.i_size; /* Initialize u_offset from file pointer */ diff --git a/Kernel/select.c b/Kernel/select.c index 30fafcc5..871e31d1 100644 --- a/Kernel/select.c +++ b/Kernel/select.c @@ -159,16 +159,16 @@ int _select(void) return -1; switch (getmode(ino)) { /* Device types that automatically report some ready states */ - case F_BDEV: - case F_REG: + case MODE_R(F_BDEV): + case MODE_R(F_REG): outr |= m; - case F_DIR: + case MODE_R(F_DIR): inr |= m; break; - case F_PIPE: + case MODE_R(F_PIPE): n = pipesel_begin(ino, n); goto setbits; - case F_CDEV: + case MODE_R(F_CDEV): /* If unsupported we report the device as read/write ready */ if (d_ioctl (ino->c_node.i_addr[0], @@ -213,11 +213,11 @@ int _select(void) if (sum & m) { ino = getinode(i); switch (getmode(ino)) { - case F_CDEV: + case MODE_R(F_CDEV): d_ioctl(ino->c_node.i_addr[0], SELECT_END, NULL); break; - case F_PIPE: + case MODE_R(F_PIPE): pipesel_end(ino); } } diff --git a/Kernel/syscall_fs2.c b/Kernel/syscall_fs2.c index 3754958c..3ef77639 100644 --- a/Kernel/syscall_fs2.c +++ b/Kernel/syscall_fs2.c @@ -10,7 +10,7 @@ static arg_t chdiroot_op(inoptr ino, inoptr * p) { - if (getmode(ino) != F_DIR) { + if (getmode(ino) != MODE_R(F_DIR)) { udata.u_error = ENOTDIR; i_deref(ino); return (-1); @@ -371,7 +371,7 @@ arg_t _acct(void) if (fd != -1) { if ((inode = getinode(fd)) == NULLINODE) return -1; - if (getmode(inode) != F_REG) { + if (getmode(inode) != MODE_R(F_REG)) { udata.u_error = EINVAL; return -1; } diff --git a/Kernel/syscall_fs3.c b/Kernel/syscall_fs3.c index aaa574f3..06a2b9f1 100644 --- a/Kernel/syscall_fs3.c +++ b/Kernel/syscall_fs3.c @@ -82,7 +82,7 @@ arg_t _open(void) goto cantopen; } if (w) { - if (getmode(ino) == F_DIR ) { + if (getmode(ino) == MODE_R(F_DIR)) { udata.u_error = EISDIR; goto cantopen; } @@ -107,7 +107,7 @@ arg_t _open(void) ino = *iptr; } - if (trunc && getmode(ino) == F_REG) { + if (trunc && getmode(ino) == MODE_R(F_REG)) { if (f_trunc(ino)) goto idrop; for (j = 0; j < OFTSIZE; ++j) @@ -127,7 +127,7 @@ arg_t _open(void) /* * Sleep process if no writer or reader */ - if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1 + if (getmode(ino) == MODE_R(F_PIPE) && of_tab[oftindex].o_refs == 1 && !(flag & O_NDELAY)) psleep(ino); @@ -167,7 +167,7 @@ arg_t _link(void) if (!(ino = n_open(name1, NULLINOPTR))) return (-1); - if (getmode(ino) == F_DIR && esuper()) + if (getmode(ino) == MODE_R(F_DIR) && esuper()) goto nogood; if (ino->c_node.i_nlink == 0xFFFF) { diff --git a/Kernel/syscall_other.c b/Kernel/syscall_other.c index ef8e8f41..2e699969 100644 --- a/Kernel/syscall_other.c +++ b/Kernel/syscall_other.c @@ -196,7 +196,7 @@ arg_t _rmdir(void) /* Fixme: check for rmdir of /. - ditto for unlink ? */ /* Not a directory */ - if (getmode(ino) != F_DIR) { + if (getmode(ino) != MODE_R(F_DIR)) { udata.u_error = ENOTDIR; goto nogood; } @@ -267,12 +267,12 @@ arg_t _mount(void) return (-1); } - if (getmode(sino) != F_BDEV) { + if (getmode(sino) != MODE_R(F_BDEV)) { udata.u_error = ENOTBLK; goto nogood; } - if (getmode(dino) != F_DIR) { + if (getmode(dino) != MODE_R(F_DIR)) { udata.u_error = ENOTDIR; goto nogood; } @@ -330,7 +330,7 @@ arg_t _umount(void) if (!(sino = n_open(spec, NULLINOPTR))) return (-1); - if (getmode(sino) != F_BDEV) { + if (getmode(sino) != MODE_R(F_BDEV)) { udata.u_error = ENOTBLK; goto nogood; } -- 2.34.1