From owner-freebsd-arch Thu Apr 6 21: 2:35 2000 Delivered-To: freebsd-arch@freebsd.org Received: from ns1.yes.no (ns1.yes.no [195.204.136.10]) by hub.freebsd.org (Postfix) with ESMTP id E139E37B992 for ; Thu, 6 Apr 2000 21:02:23 -0700 (PDT) (envelope-from eivind@bitbox.follo.net) Received: from bitbox.follo.net (bitbox.follo.net [195.204.143.218]) by ns1.yes.no (8.9.3/8.9.3) with ESMTP id GAA16318 for ; Fri, 7 Apr 2000 06:05:53 +0200 (CEST) Received: (from eivind@localhost) by bitbox.follo.net (8.8.8/8.8.6) id GAA35102 for freebsd-arch@freebsd.org; Fri, 7 Apr 2000 06:02:17 +0200 (CEST) Received: from apollo.backplane.com (apollo.backplane.com [216.240.41.2]) by hub.freebsd.org (Postfix) with ESMTP id 0105B37B992 for ; Thu, 6 Apr 2000 21:01:47 -0700 (PDT) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.9.3/8.9.1) id VAA93492; Thu, 6 Apr 2000 21:01:39 -0700 (PDT) (envelope-from dillon) Date: Thu, 6 Apr 2000 21:01:39 -0700 (PDT) From: Matthew Dillon Message-Id: <200004070401.VAA93492@apollo.backplane.com> To: Jonathan Lemon Cc: Archie Cobbs , freebsd-arch@freebsd.org Subject: Re: RFC: kqueue API and rough code References: <200004070107.SAA97591@bubba.whistle.com> <200004070220.TAA92896@apollo.backplane.com> <20000406220454.J80578@prism.flugsvamp.com> Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hey! (I snap my fingers), I got it! There is no need to copy anything back and forth from user space to kernel space! It's simple, really. How about this API: qfd = kqueue(); kqueuectl(qfd, filter, fd, struct event *ev); ev = kevent(qfd, timeout); or (another way to do kevent): n = kevent(qfd, struct event **ary, int nmax, struct timeval *timeout); The key thing here is that the kernel creates its own internal data structure which has the descriptor, filter operation, and a pointer to the *USER* event structure. The kernel would not otherwise copy the user event structure into kernel space nor would it copy it back to return the event. Instead when an event occurs the kernel does a copyout of *ONLY* the kernel data update for the event structure (the 'data') field. What it returns to user space in the kevent() call is not the event itself, but a POINTER to the event that the user originally passed it. If we do this then the user has the ability to extend the struct event structure to contain whatever the user wants. All the kernel cares about is the 'data' field. I would still reserve a bunch of fields for future direct kernel support for things like automatic function/thread dispatching, but this will result in a minimally sized in-kernel data structure and no copying back and forth (except to update the user 'data' field, which the kernel does in the kevent() syscall). The user event structure passed to the kernel (the kernel doesn't need to touch it at all except when populating 'data' when kevent() is returning events: struct event { long data; void (*dispatch)(struct event *ev); int reserved[2]; }; The kernel internal event structure (or equivalent): struct kevent { int fd; long data; /* to be copied into the uevent */ short filter; short flags; struct event *uevent; }; -Matt To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message