Thinking about kqueue's and pthread_cond_wait

Daniel Eischen eischen at vigrid.com
Wed Feb 10 18:22:18 UTC 2010


On Wed, 10 Feb 2010, Randall Stewart wrote:

>
> 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

Yes, it does.  You (the implementors of kq_create()) are suppose to
maintain the mutex and/or CV inside the kq_obj thingie and hide it
from the user of the interface.  Whatever you need to lock and
wait is embedded in kq_obj.  You will have to do some of the same
things that libthr does with umtx in pthread_mutex_{lock,unlock}
and pthread_cond_{wait,signal,broadcast}.

-- 
DE


More information about the freebsd-threads mailing list