Thinking about kqueue's and pthread_cond_wait
Randall Stewart
rrs at lakerest.net
Wed Feb 10 18:07:58 UTC 2010
On Feb 10, 2010, at 9:46 AM, Daniel Eischen wrote:
> On Wed, 10 Feb 2010, Randall Stewart wrote:
>
>>
>> On Feb 10, 2010, at 9:04 AM, Daniel Eischen wrote:
>>
>>> On Wed, 10 Feb 2010, Randall Stewart wrote:
>>>> All:
>>>> I have once again come around to thinking about joining pthread
>>>> cond waits and
>>>> kqueue's.
>>>> After thinking about it, I think its doable.. with something like
>>>> a:
>>>> pthread_cond_wait_kqueue_np(kev, cond, mtx, ucontext)
>>>> Then you can use kev inside a kqueue i.e.
>>>> ret = kevent(kq, kev, 1, outkev, 1, NULL);
>>>> Now when you saw the event:
>>>> if (kev.filter == EVFILT_UMTX){ /* not sure about the name here
>>>> */
>>>> pthread_kqueue_cond_wait_ret_np(kev, cond, mtx, ucontext)
>>>> do_user_action(cond,mtx, ucontext);
>>>> }
>>>> Which would fill in the cond/mtx and ucontext for the user.
>>>> Now does this sound useful to anyone.. i.e. should I spend the time
>>>> making it work?
>>>> The only down side to this is that it would have to allocate
>>>> memory so
>>>> one would need to do a:
>>>> pthread_kqueue_cond_wait_free_np(kev)
>>>> After you were done.. and I think it would be best for this to
>>>> be a ONE_SHOT.. i.e. you have to re-arm it if the event happens...
>>>> Of course until you free it that can be as simple as passing the
>>>> kev
>>>> back down again (i.e. no pthread_cond_wait_kqueue_np() needed).
>>>> Comments? Thoughts? i.e. especially is it worthwhile doing?
>>> Please don't mess with the pthread_ API like that :-) If you
>>> really want to munge them together, see my email to you a few
>>> weeks ago last time you brought it up.'
>>
>> If I remember right your email was basically don't do it... I will
>> go dig through the archives and re-read it all.
>
> No, it was to add an interface or two to the kqueue/kevent API, not
> to modify the pthread_ API (which shouldn't know anything about
> kqueues).
>
> I really think the OS is already given us the tools we need to
> do the job simply enough. You can easily use a pipe, socketpair,
> or EVFILT_SIGNAL to wakeup a thread stuck in kevent(). You can
> additionally use a mutex to protect data shared between thread
> waiting in kevent() and other threads.
>
> I don't see what problem this is trying to solve and I think
> whatever solution you come up with involving mutexes/CVs is
> not going to be any simpler and may even be more complex and
> messy. Mutexes and CVs are userland library thingies, not
> kernel entities. Yes, the umtx is a kernel entity, but it
> alone does not give you mutexes and CVs. So when you want
> to mix kqueues and mutexes/CVs, you are involving another
> userland library and this is what makes it messy.
You suggested:
kq = kqueue();
kq_obj = kq_create(kq, ...);
kq_lock(&kq_obj);
while (!P) {
/* Atomically unlocks kq_obj and blocks. */
nevents = kq_wait(&kq_obj, ...);
/* When you wakeup, kq_obj is locked again. */
}
do_work();
But that does not satisfy anything but the condition variable. What
would be nice is
kq = kqueue();
/* sub to various events */
EV_SET(ev, ....);
kevent(ev,...);
Then in some nice loop where threads are waiting:
while (notdone) {
nev = kevent(kq, , ev);
if (ev.fitler == EVFILTER_READ) {
handle_the_read_thingy(ev);
} else if (ev.filter == EVFILTER_COND) {
lock_mutex(if needed)
handle_condition_event();
}
}
One of the things I will note about a condition variable is that the
downside is
you ALWAYS have to have a mutex.. and not always do you need one... I
have found
multiple times in user apps where i am creating a mutex only for the
benefit of
the pthread_cond() api... sometimes just being woken up is enough ;-)
R
>
> --
> DE
>
------------------------------
Randall Stewart
803-317-4952 (cell)
803-345-0391(direct)
More information about the freebsd-threads
mailing list