From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5742 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Explaining cond var destroy [Re: [musl] C threads, v3.0] Date: Tue, 5 Aug 2014 23:52:13 -0400 Message-ID: <20140806035213.GR1674@brightrain.aerifal.cx> References: <1407144603.8274.248.camel@eris.loria.fr> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1407297154 19861 80.91.229.3 (6 Aug 2014 03:52:34 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 6 Aug 2014 03:52:34 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-5747-gllmg-musl=m.gmane.org@lists.openwall.com Wed Aug 06 05:52:27 2014 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1XEsH5-0006iB-C4 for gllmg-musl@plane.gmane.org; Wed, 06 Aug 2014 05:52:27 +0200 Original-Received: (qmail 30189 invoked by uid 550); 6 Aug 2014 03:52:26 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 30181 invoked from network); 6 Aug 2014 03:52:26 -0000 Content-Disposition: inline In-Reply-To: <1407144603.8274.248.camel@eris.loria.fr> User-Agent: Mutt/1.5.21 (2010-09-15) Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:5742 Archived-At: On Mon, Aug 04, 2014 at 11:30:03AM +0200, Jens Gustedt wrote: > diff --git a/src/thread/cnd_destroy.c b/src/thread/cnd_destroy.c > new file mode 100644 > index 0000000..7d6f3a1 > --- /dev/null > +++ b/src/thread/cnd_destroy.c > @@ -0,0 +1,21 @@ > +#include "pthread_impl.h" > +#include > + > +/* The behavior of cnd_destroy is undefined if cnd is still in > + use. The choice for pthread_cond_destroy in that situation is to > + wake up all users before destroying. I am not sure that we should > + do it like that here, too. Alternatives would be: > + - complain by using perror or equivalent > + - assert that there is no waiter > + - abort when there is a waiter > + - do nothing > + */ > +void cnd_destroy(cnd_t *c) > +{ > + int cnt; > + c->_c_destroy = 1; > + if (c->_c_waiters) > + __wake(&c->_c_seq, -1, 0); > + while ((cnt = c->_c_waiters)) > + __wait(&c->_c_waiters, 0, cnt, 0); > +} The above comment is incorrect; I'll try to explain. At least for POSIX cond vars, per POSIX, at least one thread that has called pthread_cond_[timed]wait ceases to be a waiter as soon as pthread_cond_signal is called, and all threads which have called pthread_cond_[timed]wait ceast to be waiters as soon as pthread_cond_broadcast is called. This means that, if a thread calling pthread_cond_signal or pthread_cond_broadcast has updated the predicate such that no threads will retry pthread_cond_[timed]wait or remain as waiters, it may IMMEDIATELY call pthread_cond_destroy without violating the constraint that pthread_cond_destroy can only be called when there are no waiters. Since waiters have additional work to do on the memory associated with the pthread_cond_t object after the futex wait completes, and since we do not want to force them to wake and finish this work as part of pthread_cond_signal/broadcast (this would be expensive on every signal), I've put the code to finish waiting for the waiters to wake up in pthread_cond_destroy. If you think this is a bad idea, I'd be willing to hear alternate ideas. I'm not really happy with the cond var implementation (if nothing else, the sequence number thing is an ugly hack and not 100% robust, I think) and at some point I'd like to redesign it. Rich