On Oct 7, 2012 10:56 PM, "Øyvind Teig" <oyvind.teig@teigfam.net> wrote:
>
"There is no way that I am aware of to write a prioritised select."
select {
case <-higher:
foo()
default:
select {
case <-lower:
bar()
default:
...
}
}
-j
Definitely not, although the roots must lie in the same construct.
No, what I'm saying is that the difference is one of convenience, not a natural one,
On Mon, Oct 8, 2012 at 12:33 PM, Øyvind Teig <oyvin...@teigfam.net> wrote:Where the select statement default clause is the pseudocode if
> I may be misunderstanding completely you are not pseudocoding Go.
> There is no "else if" clause in select, only comm clause and default.
statement otherwise[1]/else part:
1 select {
2 case <-higher: // 100
3 foo() // 101
4 default: // 102
On Mon, Oct 8, 2012 at 1:40 PM, Øyvind Teig <oyvin...@teigfam.net> wrote:
> But there is the problem here that both cases have default clauses.
> I only saw that now. It won't work if none are ready when select is entered.
> We don't want busy-polling. The example falls?
Falls what?
Well, actually I see what you mean, but the construct was a counter
On 8 October 2012 13:24, Øyvind Teig <oyvin...@teigfam.net> wrote:
> If you have priority select and you are a server to N clients, then being
> able to have control of the "fairness algorithm" and at the same time have
> N-pri-select then it would be a good tool.
>
> For occam, which did not have pseudo-random choice (but pretended to),
> talking with a set of N clients was typically done with two arrays of
> channels of N channels in each. These were statically made (no new). So,
> when one of the cases were taken (say index i), then that same index of the
> return channel set was used to communicate further, if a session was needed
> (no need to send the return channel across). Then, in the select (there
> could be only one, at least coneptually), during the session the other
> boolean values were false and only bool[i] would be true.
>
> Then, after the session with i, typicallly the next index ((i+1)modulo N)
> would be set up first in the select (ALT). That proved to be a very good
> fair algorithm. And from then on, if this was not good enough, well - make
> your own. Or use Go's pseudo-random as a very easy and nice choice. But not
> because that's the only way.
>
> So there definitively is a nice feature to be able to have N-pri-select.
I'm not sure I see that. I see the Occam-specific idioms (largely to
get around Occam's lack of dynamic allocation AFAICS),
but I don't
see anything that you're doing there that Go's pseudo-random
choice won't be sufficient for.
-j
> But there is no priority here. Just probability.
what is the definition of 'priority' here?
On 9 October 2012 08:04, Øyvind Teig <oyvin...@teigfam.net> wrote:
> But the problem is if like 7 of the cases above are not taken, and we come
> to the 8th (having low priority of 8th) and there is no default clause, so
> the 8th blocks, and then one of the 1-7 arrives (with higher priority) - how
> are those 1-7 then prioritised above the 8th?
This is the case I was trying to describe in my previous message.
There is no priority in this case, but I don't believe it matters.
It only matters if two or more cases become ready at *exactly* the same
time (well, in the time between the last default case and the blocking
select, which amounts to a similar thing). I believe that a genuine
prioritised select would have the same issue, albeit with a smaller
time window.
On 9 October 2012 10:12, Øyvind Teig <oyvin...@teigfam.net> wrote:
>
>
> kl. 11:01:10 UTC+2 tirsdag 9. oktober 2012 skrev rog følgende:
>>
>> On 9 October 2012 08:04, Øyvind Teig <oyvin...@teigfam.net> wrote:
>> > But the problem is if like 7 of the cases above are not taken, and we
>> > come
>> > to the 8th (having low priority of 8th) and there is no default clause,
>> > so
>> > the 8th blocks, and then one of the 1-7 arrives (with higher priority) -
>> > how
>> > are those 1-7 then prioritised above the 8th?
>>
>> This is the case I was trying to describe in my previous message.
>> There is no priority in this case, but I don't believe it matters.
>>
>> It only matters if two or more cases become ready at *exactly* the same
>> time (well, in the time between the last default case and the blocking
>> select, which amounts to a similar thing). I believe that a genuine
>> prioritised select would have the same issue, albeit with a smaller
>> time window.
>
>
> What if *none* of the cases are ready when the select is entered?
That's the case I'm trying to describe.
If no case is ready when the select is entered, the first case to
become ready will be the first case to run, regardless of its
priority. This is surely the case with Occam's PRI ALT too.
On 9 October 2012 10:25, Øyvind Teig <oyvin...@teigfam.net> wrote:
>> > What if *none* of the cases are ready when the select is entered?
>>
>> That's the case I'm trying to describe.
>
> I still don't understand. None are neither ready when select is entered nor
> ready during the assumed pickup of commevent. One that was passed on the
> list got ready "after a year", and we're hanging on the lowest priority
> (assuming no ending default). Therefore I don't understand the nanosecond
> argument either.
We're not hanging on the lowest priority - we're hanging on *all* priorities.
The first case to be ready, regardless of priority, will unblock the
select and proceed.
>> If no case is ready when the select is entered, the first case to
>> become ready will be the first case to run, regardless of its
>> priority. This is surely the case with Occam's PRI ALT too.
>
>
> I believe that occam processes the ALT atomically, and the boolean
> expressions are side effect free. I see in the "Transputer instruction set"
> that ALT evaluation starts with an "alt start" instruction. And besides, I
> haven't seen any preemptive scheduling of occam. But on the transputer, a
> physical pin could be a channel, so the "alt start" must have done the
> trick, I assume.
The question isn't whether the ALT is processed atomically, but what the
ALT does when it finds that a lower priority case has become ready. Does
it wait for a while in case a higher priority case might become ready
in the next few microseconds? Or does it just proceed with the lower
priority case anyway?
I believe that the latter is the only reasonable way to make an
efficient implementation. If that's true, the Go implementation will
behave identically to the Occam implementation when no cases are ready
on entry to the select - that is, the first case to become ready will
proceed, regardless of priority.
The Go random choice semantics do not
apply in this case.
On Tue, Oct 9, 2012 at 4:53 AM, Dan Kortschak
<dan.ko...@adelaide.edu.au> wrote:
> I think the only time it would be an issue (if this whole thing is actually an issue - which I not really convinced of) is in the case of infrequent producers the may fire together at resonably high probability. This would leave the consumer waiting in the final catch all select with the possibility of random choice of case.
You are describing a race condition. In an implementation in which
one choice must be selected and processed, race conditions are always
possible. This has nothing to do with Go.
The only way to handle the scenario you describe would be to have
preemptive channel selection: provide some way of saying that data
arriving on channel A is always handled immediately, even if we are in
the middle of handling data arriving on channel B. Go does not
support preemption of that sort.
Ian
are always ready), then you'll see the select statement working independently
of the scheduler: http://play.golang.org/p/PqGENFmeCh
To speak about a blocked select returning the
wrong channel is to speak about a race condition, because the higher
priority response might always be just slightly slower than the amount
of time you want the select to wait.
A correct program can not care
which channel is returned by a blocking select; if it does care, it
will have a race.
>> The only way to handle the scenario you describe would be to have
>> preemptive channel selection: provide some way of saying that data
>> arriving on channel A is always handled immediately, even if we are in
>> the middle of handling data arriving on channel B. Go does not
>> support preemption of that sort.
>
>
> Are you aware of any language or scheduler that would do this? I am not.
Language, no, but that's how interrupts work on a processor, and it's
what OS interrupt handlers expect to see. It's also how embedded OS's
handle events.
Ian
On 9 October 2012 22:34, Joubin Houshyar <jhou...@gmail.com> wrote:
>
> If we take the scheduler out of the equation (for example by using channels
> that
>>
>> are always ready), then you'll see the select statement working
>> independently
>> of the scheduler: http://play.golang.org/p/PqGENFmeCh
>
>
> In a way, actually user level scheduling if you take it to its conclusion:
> http://play.golang.org/p/kboO9t6RQw
Nice idea, but it doesn't really work I'm afraid. Consider what
happens if only one
of the generators is ready: http://play.golang.org/p/9CZtrI98cb
select {case r0 := <-c0:// op0..case rn := <- cn:// opndefault:// op_defselector: // optional - defaults to default_selector (built-in func)[defer?] select_function}// given selector function type// cell element true if corresponding (decl. ord.) case is available. Return selection index.type sel_fn func(available []bool) (selection int)// with a builtin default_selector mapping to current spec semantics e.g. in declaration orderfunc default_selector([]bool) int
(BTW the code to fill out the channels to select on could also use
improvement - it only ever puts a single channel in the select array,
and it crashes if the numbers don't add up, e.g.
http://play.golang.org/p/f-j1ebpqJY)
On Wed, Oct 10, 2012 at 3:56 AM, roger peppe <rogp...@gmail.com> wrote:On 9 October 2012 22:34, Joubin Houshyar <jhou...@gmail.com> wrote:
>
> If we take the scheduler out of the equation (for example by using channels
> that
>>
>> are always ready), then you'll see the select statement working
>> independently
>> of the scheduler: http://play.golang.org/p/PqGENFmeCh
>
>
> In a way, actually user level scheduling if you take it to its conclusion:
> http://play.golang.org/p/kboO9t6RQw
Nice idea, but it doesn't really work I'm afraid. Consider what
happens if only one
of the generators is ready: http://play.golang.org/p/9CZtrI98cbGood catch; missed that. You can work around that by added case of timer in a tight loop and pushing the select down from call site. Playing with various forms, there is a certain performance hit that caps throughput.Given OP's original post, it would appear trivial to have explicit selection mechanisms in Go:select {
select [selector] {...}select rndrbn_selector {...}
On Wed, Oct 10, 2012 at 3:56 AM, roger peppe <rogp...@gmail.com> wrote:On 9 October 2012 22:34, Joubin Houshyar <jhou...@gmail.com> wrote:
>
> If we take the scheduler out of the equation (for example by using channels
> that
>>
>> are always ready), then you'll see the select statement working
>> independently
>> of the scheduler: http://play.golang.org/p/PqGENFmeCh
>
>
> In a way, actually user level scheduling if you take it to its conclusion:
> http://play.golang.org/p/kboO9t6RQw
Nice idea, but it doesn't really work I'm afraid. Consider what
happens if only one
of the generators is ready: http://play.golang.org/p/9CZtrI98cbGood catch; missed that. You can work around that by added case of timer in a tight loop and pushing the select down from call site. Playing with various forms, there is a certain performance hit that caps throughput.