From owner-freebsd-commit Tue Oct 24 00:48:11 1995 Return-Path: owner-commit Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id AAA23102 for freebsd-commit-outgoing; Tue, 24 Oct 1995 00:48:11 -0700 Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id AAA23082 for cvs-all-outgoing; Tue, 24 Oct 1995 00:48:07 -0700 Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id AAA23061 for cvs-sys-outgoing; Tue, 24 Oct 1995 00:47:59 -0700 Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id AAA23019 ; Tue, 24 Oct 1995 00:47:45 -0700 Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.9/8.6.9) id RAA03491; Tue, 24 Oct 1995 17:39:03 +1000 Date: Tue, 24 Oct 1995 17:39:03 +1000 From: Bruce Evans Message-Id: <199510240739.RAA03491@godzilla.zeta.org.au> To: swallace@ece.uci.edu, terry@lambert.org Subject: Re: SYSCALL IDEAS [Was: cvs commit: src/sys/kern sysv_msg.c sysv_sem.c sysv_shm.c] Cc: CVS-commiters@freefall.freebsd.org, bde@freefall.freebsd.org, cvs-sys@freefall.freebsd.org, hackers@freebsd.org Sender: owner-commit@freebsd.org Precedence: bulk >> read(struct proc *p, void *v, int retval[]) >> { >> struct read_args /* { >> int fd; >> char *buf; >> u_int nbyte; >> } */ *uap = v; >> int fd = SCARG(uap, fd); >> char *buf = SCARG(uap, buf); >> u_int nbyte = SCARG(uap, nbyte); >> >> ... >> } >> >> That way we don't have SCARG all over the place, and this would >> prepare us for your static function idea. >Seeing this on -hackers, I'd like to have someone back up and explain >"the static function idea", static inline int read(fd, buf, nbytes) int fd; void *buf; size_t nbytes; ssize_t *retval; { /* * Same as for the current read(), except we don't have to grope * unportably in *uap for the args store the retval in an * incompatible type. */ } /* Machine generated - do not edit. */ int freebsd_syscall_entry_read(p, args, retval) struct proc *p; void *args; int *retval; { int fd; void *buf; size_t nbytes; ssize_t nread; int res; fd = machine_dependent_code_to_convert_fd_for_read(args); buf = machine_dependent_code_to_convert_buf_for_read(args); nbytes = machine_dependent_code_to_convert_nbytes_for_read(args); res = read(fd, buf, nbytes, &nread); machine_dependent_code_to_convert_retval_for_read(args, nread); return (res); } >since it seems likely that an alternate >approact to the idea might be more fruitful than rewriting the system >call interface such that we have to hack tables all over hell for >no real gain. This seems unlikely :-). The main disadvantage of the above is that read() would actually have to be non-static inline so that it can be called from emulators. E.g., foo_ossyscall_entry_read() might have different machine-generated machine-dependent code and it's much better for it to convert from that to (int fd, void *buf, size_t nbytes, ssize_t *retval) and call read() than it is to convert to the machine-dependent freebsd args array and call bsd_syscall_entry_read(). Thus read() would be duplicated at least twice (once inline for fast Freebsd syscalls, once extern for slower foo_os syscalls). All this assumes that the args are in a struct. In general, at the beginning of a syscall, some are in registers and some are in user memory. foo_os_syscall() currently has to copy them to args struct. It might be better to delay the copying to the machine-generated foo_os_syscall_entry_xxx() functions to reduce the amount of copying to the wrong places and to support messy ABI's. >> > which passes the args correctly (as void *). Then we need to handle >> > varargs functions and struct padding better. I think all the details >> > can be hidden in machine-generated functions so that the args structs >> > and verbose macros to reference them don't have to appear in the core >> > sources. >I have macros that divorce K&R and ANSI vararg behaviour from the code >itself (I use them for various things myself). Is this what we are >trying to accomplish? No. Varargs syscalls such as open(), fcntl() and shmsys() mess up the ABI. The args for them have to be copied from different places depending on codes in the early args. syscall() currently assumes that the args are on the stack in user space and copies more args than are necessary and sometimes more than are officially supplied. Varargs for syscall xxx should handled by fetching them from the appropriate place in foo_os_syscall_entry_xxx() and passing them in the normal varargs way to xxx(). > > semsys() and shmsys() syscall interfaces are BAD because they > > multiplex several syscalls that have different types of args. > > There was no reason to duplicate this sysv braindamage but now > > we're stuck with it. NetBSD has reimplemented the syscalls properly > > as separate syscalls #220-231. > > I agree. This is yucky! No, this is good -- system calls are a scarce resource and should be consumed conservatively. What's the problem you have with anonymous argument vectors using subfunction codes? No, this (not syscalls #220-231) is yucky. Multiplexing syscalls takes more code to handle even incorrectly like it does now. Non-multiplexed syscalls take one entry in sysent[] and a function to handle them; multiplexed ones require less entries in sysent[] and an extra function to demultiplex them. The demultiplexing function can be simple and unportable like the current ones or complicated and portable or machine-generated. In general it has to have code like freebsd_syscall_entry_read() for each of the variants. > We need a better way to handle these syscall subcodes (as SYSV calls 'em). I guess I don't really understand why these are a problem, unless you are trying to do something silly, like prototype them. They are a problem because they give more special cases to write code for. Bruce