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.

Reply via email to