Re: STREAMS: interface versus implementation

Jamie Lokier (lkd@tantalophile.demon.co.uk)
Wed, 16 Sep 1998 23:21:19 +0100


Alan Cox writes:
>> open("/dev/foo") for foo = tcp, udp, maybe arp, icmp, ip, eth
>
> Thats a user space problem. You can intercept open() for this

>> ioctl(fd, I_xyz, data) for various I_xyz ioctls. (Many of these just
>> need to do nothing and return 0 instead of failing with -ENOSYS.)
>
> Just overload the ioctl symbol

Albert D. Cahalan wrote:
> That stinks. While nobody expects STREAMS to be really fast,
> they shouldn't add severe overhead to libc. That includes the
> non-STREAMS part of an application that uses STREAMS.
>
> Your suggestions have a time cost in userspace. The kernel already
> handles devices and ioctls, so a few more is no overhead.

Albert, I see your point of view except I disagree with "severe". From
a technical viewpoint, let me explain why the overhead is negligible:

- The wrapper overhead is _tiny_ and you can still leave
room for a kernel implementation in future. You don't have to
strcmp against "/dev/tcp" etc. unless an open call fails:

int open (const char * name, int flags, int mode)
{
int ret = __open (name, flags, mode);
if (ret != -1 || errno != ENOENT)
return ret;
if (!strcmp (name, "/dev/tcp"))
// Blah blah
// more blah
return ret;
}

open() is not that common a call compared with, say, read() or
write().

- Even that overhead can be _totally eliminated_ in the case of normal
opens that succeed or fail with other than ENOENT.

Either put this in the glibc __open call, and catch the error case
directly, or use the _syscall3 macro. In glibc, whatever code sits in
the error case doesn't impose any overhead in the normal case.

- The ioctls can be done in a similar way, again with *no overhead* in
the normal case. Imagine the following code but arranged the way glibc
handles error cases:

int ioctl (int fd, int request, void * arg)
{
int ret = __ioctl (fd, request, arg);
if (ret != -1 || errno != EINVAL)
return ret;
if (fd < 0 || fd >= __streams_fd_table_size
|| !__streams_fd_table [fd])
return ret;
// Handle STREAMS ioctl.
}

I'm not advocating any approach here, just thought I'd point out how it
might be done reasonably efficiently in user space.

-- Jamie

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/