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