Re: The code example in onSpinWait() Javadoc
Alex Otenko via Concurrency-interest <[email protected]>
| Newsgroups | gmane.comp.java.jsr.166-concurrency |
|---|---|
| Message-ID | <CANkgWKiLxd=XK3NDTRP=FyHeT81Luu8wTjwg-myTJF3P_zUMOw@mail.gmail.com> |
I am not arguing. I want to see justification for wanting something that looks like a solution to an intractable problem. I see onSpinWait as an indicator to the JVM that it can do something useful, like possibly help FJP make some progress. I can't see how a time bound can be enforced there. Now, if you want a better timed wait, use park nanos. If you don't want to do that, how is onSpinWait meant to work? With a constraint that it isn't the same as would be suitable for a timed parking? Alex On Fri, 15 Nov 2019, 11:14 Viktor Klang, <[email protected]> wrote: > > > On Fri, 15 Nov 2019 at 12:38, Alex Otenko <[email protected]> > wrote: > >> Let's start with why you wouldn't just park nanos. Because you want the >> CPU to do something useful instead of idling. >> > > I hope you trust that I know this. :-) > > >> For a time limit to be implementable for arbitrary useful things, the >> computation done by onSpinWait must know how much time that computation >> will take - maybe to choose the computation of the right size. Gödel says >> hello >> > > Are you arguing for the removal of all polling-style API:s in Java? > > . >> >> Or you should be able to suspend that computation at arbitrary points. >> Well, not in Java. >> > > That’d be nice, but yeah, not really until Fibers. > But something crucial to factor in is wakeup delay. > > >> Alex >> >> On Fri, 15 Nov 2019, 10:25 Viktor Klang via Concurrency-interest, < >> [email protected]> wrote: >> >>> It would be interesting to have an onSpinWait(long nanos) version ehich >>> can be intrinsified if need be to provide the most accurate delay based on >>> the underlying system. >>> >>> Talking about time being meaningless in a non-RT OS is rather >>> meaningless in itself—we’re relying on getting CPU timeslices before the >>> end of the universe anyway ;) >>> >>> On Fri, 15 Nov 2019 at 12:06, Roman Leventov via Concurrency-interest < >>> [email protected]> wrote: >>> >>>> By "half-baked" I meant specifically that the example could be valid >>>> but only under specific conditions, such as core-pinned thread, or backoff >>>> timeout event, etc. However, the "mundane" class and method names which are >>>> chosen ("EventHandler") may mislead users into thinking that spin-loop is a >>>> good go-to strategy to waiting for some conditions/logic executed, instead >>>> of using a synchronization primitive or attaching a listener to a >>>> CompletableFuture/ListeanableFuture if one is involved. >>>> >>>> I like Francesco's example because it is self-contained and doesn't >>>> need any backoff, so the complicated discussion of the tradeoffs involved >>>> and conditions which should be accounted for (typical wait time, GC >>>> algorithm, busyness of the system, etc.) could be blissfully omitted. >>>> >>>> On Fri, 15 Nov 2019 at 11:05, Francesco Nigro via Concurrency-interest < >>>> [email protected]> wrote: >>>> >>>>> Hi Gil, >>>>> >>>>> It's one of the common use cases >>>>> >>>>> :) Although I can say the same I'm not quite sure that is that common >>>>> and your example re LMAX makes it even more clear (not that mine on JCTools >>>>> is better eh!) >>>>> On the other hand, onSpinWait itself is equally uncommon on j.u.c., so >>>>> I take all your points re the existing doc. >>>>> >>>>> Would a more detailed/complicated/opinionated example of a specific >>>>>> backoff flavor would help >>>>>> make the meaning and use of the method more clear, or help point out >>>>>> caveats or pitfalls better? >>>>> >>>>> My (personal) fear is that users will recognize the general busy spin >>>>> loop pattern, thinking that given that the JVM "is able to optmize it" >>>>> (thanks to help of unicorns and rainbows too) and >>>>> making it a much more attractive pairs of scissors to play with then >>>>> before :) >>>>> >>>>> >>>>> Il giorno ven 15 nov 2019 alle ore 06:38 Gil Tene <[email protected]> ha >>>>> scritto: >>>>> >>>>>> I guess I'm missing something about the starting point in this >>>>>> thread. What do you find "half baked" >>>>>> about the actual example in the Javadoc? It's one of the common use >>>>>> cases (with no time-based >>>>>> backoffs) in various applications (ones that e.g. dedicate a spinning >>>>>> thread on a dedicated core). >>>>>> >>>>>> E.g. >>>>>> https://github.com/LMAX-Exchange/disruptor/blob/5764f3b01faab603322c61cede957b7e79f58c8b/src/main/java/com/lmax/disruptor/BusySpinWaitStrategy.java >>>>>> >>>>>> There are obviously additional common variants, some of which include >>>>>> backoff mechanisms >>>>>> (time based, count based, phase of moon based, etc.), but IMO there >>>>>> is no "right way" to do this, >>>>>> and a no-backoff use case is just as valid (and maybe even common) as >>>>>> one that includes a >>>>>> backoff. The code carefully avoids spelling out how >>>>>> "eventNotificationNotReceived" is determined. >>>>>> Hey, the event may even be a backoff timeout... >>>>>> >>>>>> Would a more detailed/complicated/opinionated example of a specific >>>>>> backoff flavor would help >>>>>> make the meaning and use of the method more clear, or help point out >>>>>> caveats or pitfalls better? >>>>>> >>>>>> > On Nov 14, 2019, at 2:28 PM, Francesco Nigro via >>>>>> Concurrency-interest <[email protected]> wrote: >>>>>> > >>>>>> > Gil Tene* Android typo error >>>>>> > >>>>>> > Il gio 14 nov 2019, 23:28 Francesco Nigro <[email protected]> ha >>>>>> scritto: >>>>>> > I would like to hear the opinion of Gil Gene about it too: AFAIK he >>>>>> was the one (or one of many?) that has proposed it to be included in >>>>>> http://openjdk.java.net/jeps/285 >>>>>> > >>>>>> > Il gio 14 nov 2019, 23:22 Francesco Nigro <[email protected]> ha >>>>>> scritto: >>>>>> > 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 >>>>>> >>>>>> _______________________________________________ >>>>> 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 >>>> >>> -- >>> Cheers, >>> √ >>> _______________________________________________ >>> Concurrency-interest mailing list >>> [email protected] >>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >> -- > Cheers, > √ > _______________________________________________ Concurrency-interest mailing list [email protected] http://cs.oswego.edu/mailman/listinfo/concurrency-interest