Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Oct 1995 17:39:03 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        swallace@ece.uci.edu, terry@lambert.org
Cc:        CVS-commiters@freefall.freebsd.org, bde@freefall.freebsd.org, cvs-sys@freefall.freebsd.org, hackers@freebsd.org
Subject:   Re: SYSCALL IDEAS [Was: cvs commit: src/sys/kern sysv_msg.c sysv_sem.c sysv_shm.c]
Message-ID:  <199510240739.RAA03491@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510240739.RAA03491>