From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5928 Path: news.gmane.org!not-for-mail From: Alexander Monakov Newsgroups: gmane.linux.lib.musl.general Subject: Re: sem_getvalue conformance considerations Date: Wed, 27 Aug 2014 17:32:12 +0400 (MSK) Message-ID: References: <20140827023338.GA21076@brightrain.aerifal.cx> <1409123141.4476.18.camel@eris.loria.fr> <20140827074310.GK12888@brightrain.aerifal.cx> 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 1409146450 14521 80.91.229.3 (27 Aug 2014 13:34:10 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 27 Aug 2014 13:34:10 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-5935-gllmg-musl=m.gmane.org@lists.openwall.com Wed Aug 27 15:34:02 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 1XMdMO-0004WZ-ID for gllmg-musl@plane.gmane.org; Wed, 27 Aug 2014 15:34:00 +0200 Original-Received: (qmail 30347 invoked by uid 550); 27 Aug 2014 13:33:59 -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 30339 invoked from network); 27 Aug 2014 13:33:59 -0000 In-Reply-To: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) Xref: news.gmane.org gmane.linux.lib.musl.general:5928 Archived-At: On Wed, 27 Aug 2014, Alexander Monakov wrote: > Why wouldn't the following design work? > > val[0] is sem value if >= 0, negated waiters count otherwise > val[1] is wakeup count, incremented before futex wake, tested and decremented > by waiters returning from futex wait Unless I'm missing something, the above can simplify sem ops (sorry, eliding some details in the following pseudocode) trywait: val = sem->val[0] while (val > 0) { oldval = val; if ((val = a_cas(sem->val, val, val-1)) == oldval) return 0; } errno = EAGAIN; return -1; wait: if (atomic_fetch_and_decrement(sem->val) > 0) return 0; while (!(futex_wait(sem->val+1, 0) && errno == EINTR)) { wakecnt = sem->val[1]; while (wakecnt > 0) { oldwcnt = wakecnt; if ((wakecnt = a_cas(sem->val+1, wakecnt, wakecnt-1)) == oldwcnt) return 0; } } return -1; post: val = sem->val[0]; do { if (val == SEM_VALUE_MAX) { errno = EOVERFLOW; return -1; } oldval = val; } while ((val = a_cas(sem->val, val, val+1)) != oldval); if (val < 0) { a_inc(sem->val+1); futex_wake(sem->val+1, 1); } return 0; Alexander