From owner-freebsd-threads@FreeBSD.ORG Wed Feb 10 18:07:58 2010 Return-Path: Delivered-To: threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 462A610656A8; Wed, 10 Feb 2010 18:07:58 +0000 (UTC) (envelope-from rrs@lakerest.net) Received: from lakerest.net (unknown [IPv6:2001:240:585:2:213:d4ff:fef3:2d8d]) by mx1.freebsd.org (Postfix) with ESMTP id EFD158FC16; Wed, 10 Feb 2010 18:07:57 +0000 (UTC) Received: from mobile-166-129-159-005.mycingular.net (mobile-166-129-159-005.mycingular.net [166.129.159.5] (may be forged)) (authenticated bits=0) by lakerest.net (8.14.3/8.14.3) with ESMTP id o1AI7ned011090 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Wed, 10 Feb 2010 13:07:56 -0500 (EST) (envelope-from rrs@lakerest.net) Message-Id: <07AA24BB-DA26-406A-B24F-59E0CB36FEBE@lakerest.net> From: Randall Stewart To: Daniel Eischen In-Reply-To: Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v936) Date: Wed, 10 Feb 2010 10:07:43 -0800 References: <3581A86D-9C9C-4E08-9AD3-CD550B180CED@lakerest.net> <3CF3033E-FD13-405B-9DC6-DDE9DF4FBF37@lakerest.net> X-Mailer: Apple Mail (2.936) Cc: threads@freebsd.org Subject: Re: Thinking about kqueue's and pthread_cond_wait X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Feb 2010 18:07:58 -0000 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)