To simply this :your request is easily accommodated if all channel state changes and all selects are synchronized. This is easily doable but would crush performance.
> On May 6, 2021, at 6:11 PM, Robert Engels <reng...@ix.netcom.com> wrote: > > > > >>> On May 6, 2021, at 5:12 PM, 'Axel Wagner' via golang-nuts >>> <golang-nuts@googlegroups.com> wrote: >>> >> >>> On Thu, May 6, 2021 at 11:38 PM Robert Engels <reng...@ix.netcom.com> wrote: >> >>> Yes, but barring the nanosecs of a window this is simply implemented as Ian >>> wrote with >>> >>> Select hi >>> Default: >>> Select hi,lo >> >> No, it is not. "Barring a nanosecond" is not a guarantee. And that this is >> not actually doing what I'm asking is the entire start of my inquiry. >> >> Again: "It can't be implemented" is a valid answer to the question, though >> I'm specifically asking for details why. Posting code which doesn't do it, >> is not an answer. >> >>> If both channels are ready when the code is entered the high will always be >>> taken. >> >> But not if they are not both ready when the code is entered. Again, I was >> very specific about the guarantee I'm asking about: "If `hi` becomes ready >> before `lo` (in the sense of the memory model happens-before relationship), >> then the `hi` case should always be taken". >> > Happens before is only valid under the context of synchronization. > > While under the synchronized check it is trivial to check the channels in > order rather than pseudo randomly. > > >>> There is no such thing as simultaneous source events >> >> I am specifically talking about *non* simultaneous events. I am specifically >> talking about causally ordered events with a well-defined order, according >> to the memory model. And I > > Again, ordering is only based on synchronization. The synchronization occurs > when determining which channels are ready (and when the channel is mutated) > > >> specifically acknowledged (and originally pointed out) the impossibility to >> even assign meaning to the question in the context of concurrent events. >> >> I am specifically *not* asking about any guarantees in the case where the >> two events are concurrent. *Neither* about the low-priority communication >> becoming ready before the high priority one. I am exclusively talking about >> the situation where it can be proven that the high-priority event happens >> before the low priority one - as is the case in the example I posted. >> > > This example you give is trivial. Just remove the randomizer from the channel > selector and synchronize around all channels (global channel lock) in the > select. > > Then it will fail to exit. > >> Again: If you don't have an answer, it is fine to not respond. If you don't >> know if it's possible to implement a `select` statement with these semantics >> - or why it isn't - you don't have an answer. The point of my question is >> pure curiosity. I'm not suggesting that we add a construct like this or >> arguing it is needed or saying that I want it. I'm only curious if it could >> be done. So there is absolutely nothing lost by not getting an answer and >> there is absolutely nothing gained by trying to convince me a non-answer >> actually is one. >> >> Sorry to be so blunt, but this interaction is very frustrating. >> > I do have an answer and I’ve been very straightforward and rational. I’ve > implemented device drivers for numerous pieces of hardware and designed > circuits as well. Your thinking about some global order provided by the > memory model is incorrect. (If there were - multi process computers would > be horribly inefficient). You can implement global ordering among channels by > having a common sync/lock point - but that slows things considerably. > > I’m sorry you’re frustrated but I think that’s on you. > > > > >>> - even the first that occurred in external observed time might arrive at >>> the controller later than the second. You need full hardware and OS support >>> to even begin to minimize this possibility. Unless you have a full RTS this >>> is the best you will do with any software based solution. >>> >>>>> On May 6, 2021, at 3:15 PM, 'Axel Wagner' via golang-nuts >>>>> <golang-nuts@googlegroups.com> wrote: >>>>> >>>> >>>> To clarify again: As a litmus test, a `select` construct like the one I'm >>>> talking about would mean that this code blocks forever: >>>> https://play.golang.org/p/LcWgDcX5ojl >>>> With the current `select`, it doesn't. With a different `select`, which >>>> uses source order to express priority and under the semantics I'm asking >>>> about, this would always block, because `lo` would never be read. >>>> >>>>> On Thu, May 6, 2021 at 10:05 PM Axel Wagner >>>>> <axel.wagner...@googlemail.com> wrote: >>>>> >>>>> >>>>>> On Thu, May 6, 2021 at 9:40 PM Robert Engels <reng...@ix.netcom.com> >>>>>> wrote: >>>>>> But that is not really true because there are no constraints on if the >>>>>> source channels are buffered - if they are then my code operates >>>>>> similarly. >>>>> >>>>> I was very clear. I was asking if it is possible to implement a priority >>>>> select with the semantics "if the high priority case becomes ready before >>>>> the low priority case, it always takes the high priority case". Saying >>>>> "but what if we try to ensure that both of them are always ready" is not >>>>> answering the question. >>>>> Please stop insisting that the code you provide solves this. It simply >>>>> doesn't. Given that I phrased the question, I feel justified in claiming >>>>> the authority if it does or not. >>>>> >>>>>> Even if using unbuffered channels there is buffering being done at a >>>>>> lower level (hardware buffers, network stack buffers, etc) - so not >>>>>> “unblocking a sender” is a dubious endeavor. >>>>> >>>>> That is how select behaves, though. It chooses a communication to proceed >>>>> (currently, uniformly at random, under the premise of the question, the >>>>> highest priority one) and lets that proceed. >>>>> >>>>> If you don't have an answer to the question I posed, it is okay to just >>>>> not answer it. If there is no answer, that's okay too. But arguing about >>>>> code which clearly does not answer it is frustrating. >>>>> >>>>>> >>>>>> >>>>>>>> On May 6, 2021, at 1:30 PM, 'Axel Wagner' via golang-nuts >>>>>>>> <golang-nuts@googlegroups.com> wrote: >>>>>>>> >>>>>>> >>>>>>>> On Thu, May 6, 2021 at 8:22 PM Robert Engels <reng...@ix.netcom.com> >>>>>>>> wrote: >>>>>>> >>>>>>>> “If lo” means that if the lo channel was read. >>>>>>> >>>>>>> Exactly. To fulfill the requirements and answering the question, it >>>>>>> must not be read. >>>>>>> >>>>>>>> This code will prevent a lo from being processed if a hi is available >>>>>>>> at the happens before moment of a value being ready. >>>>>>> >>>>>>> What the receiver does with the value is immaterial. Point is, that the >>>>>>> receiver has already read the value, thus the communication has >>>>>>> happened, thus the sender was unblocked. The question is about a select >>>>>>> that wouldn't do that. >>>>>>> >>>>>>>> Btw using indents rather than brackets in the above - maybe that is >>>>>>>> causing the confusion. >>>>>>> >>>>>>> I'm not confused. Your code is simply not answering the question posed. >>>>>>> Which is about a select which always lets the high priority >>>>>>> communication happen, if it is ready before the low priority >>>>>>> communication - and consequently *doesn't* let the low priority >>>>>>> communication happen. >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>>> On May 6, 2021, at 12:37 PM, 'Axel Wagner' via golang-nuts >>>>>>>>>> <golang-nuts@googlegroups.com> wrote: >>>>>>>>>> >>>>>>>>> >>>>>>>>> No, it is not. Your "if lo" branch implies that the communication >>>>>>>>> happened - e.g. the sender was already unblocked. A `select` would >>>>>>>>> not unblock the other side unless that's the actual branch taken. >>>>>>>>> >>>>>>>>>> On Thu, May 6, 2021 at 7:32 PM Robert Engels <reng...@ix.netcom.com> >>>>>>>>>> wrote: >>>>>>>>>> I already showed you - just change it to >>>>>>>>>> >>>>>>>>>> Select hi >>>>>>>>>> Default: >>>>>>>>>> Select hi,lo >>>>>>>>>> If lo: >>>>>>>>>> Select hi >>>>>>>>>> Default : >>>>>>>>>> Pass >>>>>>>>>> >>>>>>>>>> And enqueue the lo if a hi and lo are read. >>>>>>>>>> >>>>>>>>>> That is all that is needed. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>>> On May 6, 2021, at 10:28 AM, 'Axel Wagner' via golang-nuts >>>>>>>>>>>> <golang-nuts@googlegroups.com> wrote: >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> On Thu, May 6, 2021 at 4:43 PM roger peppe <rogpe...@gmail.com> >>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, 6 May 2021 at 14:41, 'Axel Wagner' via golang-nuts >>>>>>>>>>>>>> <golang-nuts@googlegroups.com> wrote: >>>>>>>>>>>>>> PS: And I'm not saying there is no argument. Maybe "select is >>>>>>>>>>>>>> not atomic" is such an argument. But if there is an argument >>>>>>>>>>>>>> and/or if this is that argument, I don't fully understand it >>>>>>>>>>>>>> myself. >>>>>>>>>>>>> >>>>>>>>>>>>> One reason is that the semantics can conflict. Consider this >>>>>>>>>>>>> code, for example (assuming a hypothetical "pri select" statement >>>>>>>>>>>>> that chooses the first ready arm of the select) - the priorities >>>>>>>>>>>>> conflict. I suspect Occam doesn't encounter that issue because it >>>>>>>>>>>>> only allows (or at least, it did back when I used Occam) select >>>>>>>>>>>>> on input, not output. I believe that restriction was due to the >>>>>>>>>>>>> difficulty of implementing bidirectional select between actual >>>>>>>>>>>>> distributed hardware processors, but I'm sure Øyvind knows better. >>>>>>>>>>>>> >>>>>>>>>>>>> func main() { >>>>>>>>>>>>> c1, c2, c3 := make(chan int), make(chan int), make(chan >>>>>>>>>>>>> int) >>>>>>>>>>>>> >>>>>>>>>>>>> go func() { >>>>>>>>>>>>> pri select { >>>>>>>>>>>>> case c1 <- 1: >>>>>>>>>>>>> case v := <-c2: >>>>>>>>>>>>> c3 <- v >>>>>>>>>>>>> } >>>>>>>>>>>>> }() >>>>>>>>>>>>> go func() { >>>>>>>>>>>>> pri select { >>>>>>>>>>>>> case c2 <- 2: >>>>>>>>>>>>> case v := <-c1: >>>>>>>>>>>>> c3 <- v >>>>>>>>>>>>> } >>>>>>>>>>>>> }() >>>>>>>>>>>>> fmt.Println(<-c3) >>>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> Interesting case. I would argue, though, that there is no >>>>>>>>>>>> happens-before edge here to order the cases and I was only >>>>>>>>>>>> considering providing a guarantee if there is one. >>>>>>>>>>>> >>>>>>>>>>>> That said, I suspect that the semantics could be ironed out, and >>>>>>>>>>>> the real reason for Go's lack is that it's not actually that >>>>>>>>>>>> useful; that it would be one more feature; and that in practice a >>>>>>>>>>>> random choice makes sense almost all the time. >>>>>>>>>>> >>>>>>>>>>> As I said, this would certainly satisfy me as an answer :) >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>>> On Thu, May 6, 2021 at 3:40 PM Axel Wagner >>>>>>>>>>>>>> <axel.wagner...@googlemail.com> wrote: >>>>>>>>>>>>>> FWIW after all this discussion I *am* curious about a more >>>>>>>>>>>>>> detailed argument for why we can't have a priority select that >>>>>>>>>>>>>> guarantees that if the high-priority case becomes ready before >>>>>>>>>>>>>> the low-priority one (in the sense of "there exists a >>>>>>>>>>>>>> happens-before edge according to the memory model"), the >>>>>>>>>>>>>> high-priority will always be chosen. >>>>>>>>>>>>>> >>>>>>>>>>>>>> That is, in the example I posted above, we do know that `hi` >>>>>>>>>>>>>> becoming readable happens-before `lo` becoming readable, so a >>>>>>>>>>>>>> true prioritized select would always choose `hi` and never >>>>>>>>>>>>>> return. The construct we presented does return. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Now, I do 100% agree that it's not possible to have a select >>>>>>>>>>>>>> that guarantees that `hi` will be read if both become readable >>>>>>>>>>>>>> concurrently. But I don't see a fundamental issue with having a >>>>>>>>>>>>>> select that always chooses `hi` if `hi` becoming readable >>>>>>>>>>>>>> happens-before `lo` becoming readable. >>>>>>>>>>>>>> >>>>>>>>>>>>>> And to be clear, I also kinda like that we don't have that - I >>>>>>>>>>>>>> think the value provided by the pseudo-random choice in >>>>>>>>>>>>>> preventing starvation is worth not having an "ideal" priority >>>>>>>>>>>>>> select construct in the language. But I couldn't really make a >>>>>>>>>>>>>> good case why we can't have it. >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> 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/CAEkBMfEJNtu1i1RyZxW5FNYkD0TB73nq0WyVCCW_E9_JOAVJmw%40mail.gmail.com. >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> 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/CAEkBMfHEEDdL8adBDFoqwVHswK3kr_KawePGi%3DNtbaBVTP5KWw%40mail.gmail.com. >>>>>>>>> >>>>>>>>> -- >>>>>>>>> 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/CAEkBMfHv2cKR1OLS97YN7JYKZXHu_s0a-6c0-2tW%3DS0gUU8jUA%40mail.gmail.com. >>>>>>> >>>>>>> -- >>>>>>> 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/CAEkBMfHQq2p60OenLMYUFz%3DK9HigpbAqj7m%3D%2BRp7BnCX%2Bp1QLA%40mail.gmail.com. >>>> >>>> -- >>>> 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/CAEkBMfHL_G5bGs6tGXO6U8H%3DYMNf6f3%2B4V1JDxALEfOpGhQjvA%40mail.gmail.com. >> >> -- >> 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/CAEkBMfFwhUCbRMO1pAwJWkky2WtJh2hieV4D6_66aUpyhtMc4A%40mail.gmail.com. -- 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/EA812B89-C832-49C5-952C-666903143CB1%40ix.netcom.com.