[concurrency-interest] The code example in onSpinWait() Javadoc

Alex Otenko oleksandr.otenko at gmail.com
Fri Nov 15 08:31:12 EST 2019


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, <viktor.klang at gmail.com> wrote:

>
>
> On Fri, 15 Nov 2019 at 12:38, Alex Otenko <oleksandr.otenko at gmail.com>
> 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, <
>> concurrency-interest at cs.oswego.edu> 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 <
>>> concurrency-interest at cs.oswego.edu> 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 <
>>>> concurrency-interest at cs.oswego.edu> 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 <gil at azul.com> 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 <concurrency-interest at cs.oswego.edu> wrote:
>>>>>> >
>>>>>> > Gil Tene* Android typo error
>>>>>> >
>>>>>> > Il gio 14 nov 2019, 23:28 Francesco Nigro <nigro.fra at gmail.com> 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 <nigro.fra at gmail.com> 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 <oleksandr.otenko at gmail.com>
>>>>>> 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, <concurrency-interest at cs.oswego.edu> 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 <
>>>>>> nathanila at gmail.com> 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 <
>>>>>> aph at redhat.com> 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
>>>>>> > Concurrency-interest at cs.oswego.edu
>>>>>> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>>>> > _______________________________________________
>>>>>> > Concurrency-interest mailing list
>>>>>> > Concurrency-interest at cs.oswego.edu
>>>>>> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>>>>
>>>>>> _______________________________________________
>>>>> Concurrency-interest mailing list
>>>>> Concurrency-interest at cs.oswego.edu
>>>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>>>
>>>> _______________________________________________
>>>> Concurrency-interest mailing list
>>>> Concurrency-interest at cs.oswego.edu
>>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>>
>>> --
>>> Cheers,
>>>>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.edu
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>
>> --
> Cheers,
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20191115/e0565791/attachment-0001.html>


More information about the Concurrency-interest mailing list