From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/7111 Path: news.gmane.org!not-for-mail From: Alexander Monakov Newsgroups: gmane.linux.lib.musl.general Subject: Re: semaphore redesign Date: Sun, 1 Mar 2015 21:24:09 +0300 (MSK) Message-ID: References: <1409123141.4476.18.camel@eris.loria.fr> <20140827074310.GK12888@brightrain.aerifal.cx> <20150301173048.GD16260@port70.net> 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 1425234273 3313 80.91.229.3 (1 Mar 2015 18:24:33 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 1 Mar 2015 18:24:33 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-7124-gllmg-musl=m.gmane.org@lists.openwall.com Sun Mar 01 19:24:33 2015 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1YS8XZ-0004eT-9V for gllmg-musl@m.gmane.org; Sun, 01 Mar 2015 19:24:33 +0100 Original-Received: (qmail 18325 invoked by uid 550); 1 Mar 2015 18:24:31 -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 18227 invoked from network); 1 Mar 2015 18:24:21 -0000 In-Reply-To: <20150301173048.GD16260@port70.net> User-Agent: Alpine 2.11 (LNX 23 2013-08-11) Xref: news.gmane.org gmane.linux.lib.musl.general:7111 Archived-At: On Sun, 1 Mar 2015, Szabolcs Nagy wrote: > * Alexander Monakov [2015-02-28 02:21:22 +0300]: > > int sem_post(sem_t *sem) > > { > > int val; > > do { > > val = sem->__val[0]; > > if (val == SEM_VALUE_MAX) { > > errno = EOVERFLOW; > > return -1; > > as discussed on irc early return here without a barrier is not ok > (it is a hard to observe corner case, i add the comment here so > it does not get forgotten) We further discussed that to fix it, one can recheck the value after a barrier in the error path, and restart from the beginning if it changed, or always proceed to CAS (with value changed only if not leading to error), and handle errors after the cas-retry loop. The following code implements the latter approach. I strongly prefer it for sem_trywait, where I think EAGAIN is relatively common. For sem_post it's not so clear cut for me, as EOVERFLOW should be extremely rare, but still it helps to get good code layout from the compiler (otherwise GCC lays out error return path inside of the cas loop). int sem_trywait(sem_t *sem) { int val; do val = sem->__val[0]; while (val != a_cas(sem->__val, val, val-!!(val>0))); if (val > 0) return 0; errno = EAGAIN; return -1; } int sem_post(sem_t *sem) { int val; do val = sem->__val[0]; while (val != a_cas(sem->__val, val, val+!!(val__val[2]; a_inc(sem->__val+1); __wake(sem->__val+1, 1, priv); } if (val < SEM_VALUE_MAX) return 0; errno = EOVERFLOW; return -1; }