Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Apr 2000 00:19:29 -0500
From:      Jonathan Lemon <jlemon@flugsvamp.com>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        Jonathan Lemon <jlemon@flugsvamp.com>, Archie Cobbs <archie@whistle.com>, freebsd-arch@freebsd.org
Subject:   Re: RFC: kqueue API and rough code
Message-ID:  <20000407001929.N80578@prism.flugsvamp.com>
In-Reply-To: <200004070340.UAA93335@apollo.backplane.com>
References:  <200004070107.SAA97591@bubba.whistle.com> <200004070220.TAA92896@apollo.backplane.com> <20000406220454.J80578@prism.flugsvamp.com> <200004070340.UAA93335@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
I won't analyze this too much, since I think that with Matt's
next reply, we moved much closer to an agreement.  But I wanted
to comment on a few things:


On Thu, Apr 06, 2000 at 08:40:19PM -0700, Matthew Dillon wrote:
>     Consider a program that is linked against three or four third party
>     libraries... for example, consider a program linked against the X11
>     libraries.
> 
>     Now lets say that the X11 libraries are multi-threaded and want to use
>     the kernel queue mechanism to handle events asynchronously in the
>     user space of the program using the library.
> 
>     It is not possible for the X11 libraries to do this if they happen to use
>     a different dispatch mechanism then your main loop uses.  In fact, if you
>     look at how X (and other non-embedded subsystems) are organized, it is
>     precisely this problem that leads to an inability to scale their 
>     interfaces.  i.e. you can't use your neat cool event mechanism if you 
>     have to call another library's code that serves as the main loop for your
>     program rather then you being able to serve as the main loop for your
>     program.

My vision in this scenario is that each library will create it's own
kqueue, and register the events that it is interested in within that
kqueue.  This way there is no conflict between events registered by
a library, and those registered by the main program.  (recall that the
uniqifier for an event within a kqueue is (ident/filter).

The libraries then either run in their own thread, and register their
thread with the main process, _or_ they register the kq descriptor 
with the main process, and the process calls the library when there 
is an event pending.

	main code:
		poll( bunch of kq's )
	  	call_library(kq)

	library:
		event = kevent(kq, ....)
			

>     /*
>      * Module implements an asynchronous write with timeout.
>      */
>     somemodule_messing_with_some_tcp_connection(struct manage *m)
>     {
> 	setdispatch(m->fd, m, module_write, priority, EVENT_WRITE);
> 	setdispatch(m->fd, m, module_read, priority, EVENT_READ);
> 	/* returns here */
>     }
> 
>     module_write(int fd, struct manage *m, int r)
>     {
> 	issues write and either clears the dispatch function
> 	or allows it to remain, depending.
>     }
> 
>     module_read(int fd, struct manage *m, int r)
>     {
> 	issues read, deals with read data.
>     }

As a matter of fact, this pretty closely matches a project that I'm
working on.  What's missing here is the definition of setdispatch()
and dispatch().

I see these as being:

	setdispatch(fd, m, function, priority, filter) 
	{
		kq = module_kq(m);
		save_info(fd, filter, m, function, priority, ....)
		kevent(kq, fd, filter, ...)
	}

	dispatch()
	{
		(fd, filter, data) = fetch_event(kq)
		(fcn, m, pri) = retrieve_info(kq, fd, filter) 
		fcn(m, fd, r, data)
	}

Note that the only difference is that this forces the user to 
keep a (fd/filter) --> udata mapping table; I agree that by
allowing this pointer to be passed to/from the kernel, it can 
save the application some lookup time.


>     Notice a couple of things?  Like for example the above code is 
>     completely independant of any other module or library.  It does not
>     require a central loop to read events nor does it have to use the
>     same support library that some other library might use to implement
>     event handling.  But only if the event dispatch and user data
>     ('m' in this case, which the kernel does not interpret but simply
>     passes to the event handler) are directly supported by the kernel.

In essence, you seem to be arguing for a dispatch() mechanism in
the kernel, which allows functions to be registered, and the kernel
makes a direct callback.  Without this, you still have to have a 
user-level dispatcher, which pulls events off a queue and then does
the dispatch.  However, the mechanism here isn't designed to be a
dispatch function, although it doesn't preclude later implementation
of one either.
--
Jonathan




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




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