On Thu, Jul 25, 2019 at 1:44 AM Ian Lance Taylor <i...@golang.org> wrote: > > On Wed, Jul 24, 2019 at 11:24 AM shivaram via golang-nuts > <golang-nuts@googlegroups.com> wrote: > > > > Several sources, including this issue comment: > > > > https://github.com/golang/go/issues/27544#issuecomment-419265234 > > > > state that a buffered channel of size 1 can be used as a trylock by > > select'ing on it with a default case. > > > > I was thinking about it and it seemed to me that with such an > > implementation, it is unclear whether a failed acquisition of the trylock > > guarantees that the lock is held by someone else. More precisely, I can't > > tell if the following guarantee holds: a failed acquisition of the trylock > > cannot happen-before a successful acquisition, unless a release > > happens-between them. (To put it another way: can there be "spurious" > > failures of trylock acquisition?) > > In any realistic program, a lock may be held by a different goroutine > as the trylock starts and released as the trylock ends. So it is > always possible for trylock acquisition to fail but for the lock to be > unlocked after trylock completes.
As I see it, the problem is that failed acquisitions of a channel-based trylock do not create any happens-before edges with successful releases or acquisitions. In contrast, x/sync/semaphore does create these edges, because calls to Acquire, TryAcquire, and Release are all ordered by the acquisition and release of `mu`: https://github.com/golang/sync/blob/112230192c580c3556b8cee6403af37a4fc5f28c/semaphore/semaphore.go so it cannot happen that a failed TryAcquire is followed by a successful TryAcquire unless there's a Release in between. > > In particular: > > > > 1. The memory model documentation states ordering guarantees for > > *successful* channel receives and sends, but doesn't say anything about > > failed nonblocking receives and sends, so it seems to me that in principle > > it can't be promising anything about this behavior. > > > > 2. I can't tell whether the fast-path checks in the current implementation > > allow for this: > > > > https://github.com/golang/go/blob/919594830f17f25c9e971934d825615463ad8a10/src/runtime/chan.go#L159 > > https://github.com/golang/go/blob/919594830f17f25c9e971934d825615463ad8a10/src/runtime/chan.go#L437 > > > > In particular, I don't understand why `chanrecv` does an atomic read of > > `qcount`, but `chansend` just does a normal read. > > This is explained by the comments about read ordering and order of operations. Thanks! > Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CACC3uVGZbNrEE4fLVRQ6ehSE%2BQG7ngkkvTVrGEj_UijMn0GqRA%40mail.gmail.com.