Re: The code example in onSpinWait() Javadoc
Alex Otenko via Concurrency-interest <[email protected]>
| Newsgroups | gmane.comp.java.jsr.166-concurrency |
|---|---|
| Message-ID | <CANkgWKi65MFdm_HEdBFkcU36zRL5K2dKVvWMztt+RTFjRe4E9g@mail.gmail.com> |
That's the thing, I don't see what is more complex or more instructive about the differently written loop that breaks on observing a 1-bit state change. When I hear "time" pronounced in the context of wait, I shudder. Strict time bound makes no sense in a non real time OS. You can only formulate a termination condition in terms of happens before. So you can only say "10ms elapses before I will break out of the wait loop". But you don't need onSpinWait to know that. In fact, you just can't implement it without a computation model with arbitrary suspension points. Alex On Thu, 14 Nov 2019, 22:22 Francesco Nigro, <[email protected]> wrote: > Beside being more complex? > Not much I admit :) > But IMO awaiting with no algorithmical indication of the duration of the > wait (like in the javadoc) and awaiting for a finite amount of "time" a > condition that will be true at some point, is a better example where to > apply onSpinWait, although is not technically incorrect to use it for > "blind" spin loop as well. > Maybe is just a subtle difference, but I won't encourage users to blindly > spin loop on conditions and just use onSpinWait to save the day.. probably > I'm worried too much for something very simple and unavoidable; as @roman > has suggested, probably no example is better then one that is a superclass > of all the possible best cases. > > > Il gio 14 nov 2019, 22:51 Alex Otenko <[email protected]> ha > scritto: > >> What's the difference between this example and what's in javadocs? >> >> Alex >> >> On Thu, 14 Nov 2019, 16:29 Francesco Nigro via Concurrency-interest, < >> [email protected]> wrote: >> >>> Totally right, sorry again (writing by phone is a terrible idea :( ): >>> yes , poll should use "o = this.obj". >>> >>> > Can we get rid of "done"? Since offerOnce() does not allow null, >>> then having the done flag does not seem to help anything. >>> Absolutely yes: I've prepared this as a "simplified" (and wrong due to >>> the hurry, sorry for that) version of what we do on many queues in JCtools, >>> that's why it contains some unnecessary bits as you've rightly pointed >>> out. >>> Code that is spin awaiting on a condition, sure that it will happen at >>> some point in the future, is something that could help to understand the >>> rare cases >>> where using onSpinWait could be beneficial IMO. >>> >>> >>> >>> Il giorno gio 14 nov 2019 alle ore 17:18 Nathan and Ila Reynolds < >>> [email protected]> ha scritto: >>> >>>> In poll(), should "this.obj = o" be "o = this.obj"? Without this >>>> change, it seems poll() could spin forever. >>>> >>>> Should "poll" be renamed to "take" since the method could block until a >>>> value is available? >>>> >>>> Can we get rid of "done"? Since offerOnce() does not allow null, then >>>> having the done flag does not seem to help anything. >>>> >>>> Is the compiler and execution engine in my head misinterpreting and >>>> mis-executing the code? >>>> >>>> Here is the code with my suggested changes. >>>> volatile E obj = null; >>>> >>>> public void offerOnce(E o) { >>>> Objects.checkNonNull(o); >>>> this.obj = o; >>>> } >>>> >>>> public boolean isDone() { >>>> return obj != null; >>>> } >>>> >>>> public E take() { >>>> E o; >>>> >>>> while (true) { >>>> o = obj; >>>> >>>> if (o != null) >>>> return o; >>>> >>>> java.lang.Thread.onSpinWait(); >>>> } >>>> } >>>> >>>> -Nathan >>>> >>>> On 11/14/2019 8:54 AM, Francesco Nigro wrote: >>>> >>>> Sorry I've written on the email text, I forgot an important part, let >>>> me write it properly: >>>> >>>> volatile E obj = null; >>>> volatile boolean done = false; >>>> >>>> public void offerOnce(E o) { >>>> Objects.checkNonNull(o); >>>> this.done = true; >>>> this.obj = o; >>>> } >>>> >>>> public boolean isDone() { >>>> return done; >>>> } >>>> >>>> public E poll() { >>>> E o = this.obj; >>>> if (o == null && !this.done) { >>>> return null; >>>> } >>>> //o will be !null at some point >>>> do { >>>> if (o != null) >>>> return o; >>>> java.lang.Thread.onSpinWait(); >>>> this.obj = o; >>>> } while(true); >>>> } >>>> >>>> Similarly to the queue API: poll should return null iff !done, but >>>> offer update first done and then this.obj: >>>> poll need to read obj, but has to stay consistent to the ordering, so >>>> at some point, obj will be visible if done == true. >>>> On JCtools we have some queues with a similar behaviour (producer >>>> sequence is advanced before writing the actual element in the queue) >>>> and we need to spin wait the element apprearence to stay consistent >>>> with the isEmpty behaviour: that's a good use case for onSpinWait (when it >>>> works :P). >>>> >>>> >>>> >>>> Il giorno gio 14 nov 2019 alle ore 16:43 Andrew Haley <[email protected]> >>>> ha scritto: >>>> >>>>> On 11/14/19 3:31 PM, Francesco Nigro via Concurrency-interest wrote: >>>>> > E o = this.obj; >>>>> > if (o == null && !done) { >>>>> > return null; >>>>> > } >>>>> > //o will be !null at some point >>>>> > do { >>>>> > if (o != null) >>>>> > return o; >>>>> > java.lang.Thread.onSpinWait(); >>>>> > } while(true); >>>>> > } >>>>> > >>>>> > In case like this is more appropriate, maybe, but much less intuitive >>>>> > probably. >>>>> >>>>> Umm, what? o is a local. This loop spins forever. >>>>> >>>>> -- >>>>> Andrew Haley (he/him) >>>>> Java Platform Lead Engineer >>>>> Red Hat UK Ltd. <https://www.redhat.com> >>>>> https://keybase.io/andrewhaley >>>>> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 >>>>> >>>>> _______________________________________________ >>> Concurrency-interest mailing list >>> [email protected] >>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >> _______________________________________________ Concurrency-interest mailing list [email protected] http://cs.oswego.edu/mailman/listinfo/concurrency-interest