Forgot the references, sorry about that: [1] http://wiki.hiit.fi/display/psirpcode/Blackhawk
[2] www.psirp.org --Pekka Nikander On 2010-08 -30, at 15:54 , Pekka Nikander wrote: > We are trying to interface the Blackhawk memory-sharing > publish/subscribe-based IPC system [1], developed in the PSIRP project [2], > with Click, initially at the user level. > > One particular problem that we are facing is that the Blackhawk IPC is > heavily based on using EVFILT_VNODE kevents, even extending them at the > kernel side. Now, Click as it is currently only supports EVFILT_READ and > EVFILT_WRITE kevents. While it would be possible to change Blackhawk to > support them, too, in addition to EVFILT_VNODE kevents, it would not be > sufficient since Blackhawk also uses the kevent->udata field for houskeeping, > and Click's Master class does not support it. > > Thus, we have ended up looking at how to extend the Master class to have > better kevent support, in a way that would also benefit others and not only > our project. Right now we have made some minimal changes to the Master > class, allowing it to be more easily subclassed, and created a subclass of > Master, called KqueueMaster. However, this approach has the problem that we > also need to modify the click.cc itself, to instantiate a KqueueMaster > instead of the regular Master, an approach that I don't consider very > elegant. It works for now, but it is not nice. > > Hence, I'm looking for advice and opinions on how to approach the issue. Our > initial patch (the master.{hh,cc} part) included below. > > --Pekka Nikander > > diff --git a/include/click/master.hh b/include/click/master.hh > index f0cc360..e2c4861 100644 > --- a/include/click/master.hh > +++ b/include/click/master.hh > @@ -69,6 +69,15 @@ class Master { public: > static volatile sig_atomic_t signals_pending; > #endif > > +#if CLICK_KQUEUE_MASTER > + protected: > + void select_lock_acquire(); > + void select_lock_release(); > + void register_kqueue(int fd, short filter, u_int fflags, > + intptr_t d, void *ud); > + virtual void call_kqueued(int fd, struct kevent *event); > +#endif > + > private: > > // stick _timer_expiry here so it will most likely fit in a cache line, > @@ -360,5 +369,19 @@ Element::master() const > return _router->master(); > } > > +#if CLICK_KQUEUE_MASTER > +inline void Master::select_lock_acquire() { > + _select_lock.acquire(); > +} > + > +inline void Master::select_lock_release() { > + _select_lock.release(); > +} > + > +inline void Master::call_kqueued(int /*fd*/, struct kevent */*event*/) { > + // Do nothing > +} > +#endif > + > CLICK_ENDDECLS > #endif > > diff --git a/lib/master.cc b/lib/master.cc > index 95ee585..1c80282 100644 > --- a/lib/master.cc > +++ b/lib/master.cc > @@ -535,6 +535,26 @@ Master::run_timers() > > #if CLICK_USERLEVEL > > +# if CLICK_KQUEUE_MASTER > +void > +Master::register_kqueue(int fd, short filter, u_int fflags, intptr_t d, void > *ud) { > + if (_kqueue >= 0) { > + // Add events to the kqueue > + struct kevent kev[2]; > + int nkev = 0; > + EV_SET(&kev[nkev], fd, filter, EV_ADD, fflags, d, ud); > + nkev++; > + int r = kevent(_kqueue, &kev[0], nkev, 0, 0, 0); > + if (r < 0) { > + // Not all file descriptors are kqueueable. So if we encounter > + // a problem, fall back to select() or poll(). > + close(_kqueue); > + _kqueue = -1; > + } > + } > +} > +# endif > + > namespace { > enum { SELECT_READ = Element::SELECT_READ, SELECT_WRITE = > Element::SELECT_WRITE }; > } > @@ -560,6 +580,14 @@ Master::register_select(int fd, bool add_read, bool > add_write) > _pollfds[pi].events |= POLLOUT; > > #if HAVE_USE_KQUEUE > +# if CLICK_KQUEUE_MASTER > + if (add_read) { > + register_kqueue(fd, EVFILT_READ, 0, 0, EV_SET_UDATA_CAST ((intptr_t) > 0)); > + } > + if (add_write) { > + register_kqueue(fd, EVFILT_WRITE, 0, 0, EV_SET_UDATA_CAST ((intptr_t) > 0)); > + } > +# else > if (_kqueue >= 0) { > // Add events to the kqueue > struct kevent kev[2]; > @@ -580,6 +608,7 @@ Master::register_select(int fd, bool add_read, bool > add_write) > _kqueue = -1; > } > } > +# endif > #endif > #if !HAVE_POLL_H || HAVE_USE_SELECT > @@ -839,6 +868,10 @@ Master::run_selects_kqueue(RouterThread *thread, bool > more_tasks) > mask |= Element::SELECT_READ; > else if (p->filter == EVFILT_WRITE) > mask |= Element::SELECT_WRITE; > +# if CLICK_KQUEUE_MASTER > + else > + call_kqueued(fd, p); > +# endif > call_selected(fd, mask); > } > } > > > _______________________________________________ > click mailing list > click@amsterdam.lcs.mit.edu > https://amsterdam.lcs.mit.edu/mailman/listinfo/click _______________________________________________ click mailing list click@amsterdam.lcs.mit.edu https://amsterdam.lcs.mit.edu/mailman/listinfo/click