-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
primitiveYield (167) interferes with temporal #priority: bumping #677
Comments
I don't think that's a bug. However, your example should not need to |
I agree with Vanessa. We either need a primitive to set a process’s priority rather than relying on assigning to its priority inst var. or we need a primitive which is invoked after a priority change. I’m not sure what the most convenient thing is, but my hunch is that the latter is more useful, but somewhat more difficult to explain ;-) |
On Thu, Mar 28, 2024 at 2:56 PM Eliot Miranda via Vm-dev < ***@***.***> wrote:
I agree with Vanessa. We either need a primitive to set a process’s
priority rather than relying on assigning to its priority inst var. or we
need a primitive which is invoked after a priority change. I’m not sure
what the most convenient thing is, but my hunch is that the latter is more
useful, but somewhat more difficult to explain ;-)
Couldn't you just modify Process >> priority: to invoke the primitive
whenever a priority is set? Then no explanation is necessary. Just a
comment to explain that it is used to manage priority changes. If
the process is not running the primitive does nothing.
Ron
… —
Reply to this email directly, view it on GitHub
<#677 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AIJPEWZ7PEBPJYLTA6F7LADY2RRUFAVCNFSM6AAAAABFNAWVFKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRVHEYDCOJQGQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Wonder if any existing prim would do the right thing? Like suspending after setting priority maybe? |
Hi Ron,
On Thu, Mar 28, 2024 at 2:47 PM Ron Teitelbaum ***@***.***> wrote:
On Thu, Mar 28, 2024 at 2:56 PM Eliot Miranda via Vm-dev <
***@***.***> wrote:
>
>
> I agree with Vanessa. We either need a primitive to set a process’s
> priority rather than relying on assigning to its priority inst var. or we
> need a primitive which is invoked after a priority change. I’m not sure
> what the most convenient thing is, but my hunch is that the latter is more
> useful, but somewhat more difficult to explain ;-)
>
Couldn't you just modify Process >> priority: to invoke the primitive
whenever a priority is set? Then no explanation is necessary. Just a
comment to explain that it is used to manage priority changes. If
the process is not running the primitive does nothing.
That sounds nice and simple. I'll go with that. The primitive can check
for a runnable process simply:
- the active process has no myList
- a quiescent process (runnable but not the running one) has as its myList
the list in the quiescentProcesseLists array indexed by its priority.
So if neither of these is true the primitive can fail, and the fall-through
code can set the inst var.
Ron
> —
> Reply to this email directly, view it on GitHub
> <#677 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AIJPEWZ7PEBPJYLTA6F7LADY2RRUFAVCNFSM6AAAAABFNAWVFKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRVHEYDCOJQGQ>
> .
> You are receiving this because you are subscribed to this thread.Message
> ID: ***@***.***>
>
_,,,^..^,,,_
best, Eliot
|
On Thu, Mar 28, 2024 at 2:58 PM Vanessa Freudenberg < ***@***.***> wrote:
Wonder if any existing prim would do the right thing? Like suspending
after setting priority maybe?
suspend/resume works for all senders other than the active process itself,
which won't proceed from the suspend :-(
I don't think there are any existing primitives that do the job. Process
is nice and simple, two prims for suspend & resume (ok, there are three
varieties of suspend, but we effectively only use one of them).
_,,,^..^,,,_
best, Eliot
|
I'd prefer if the primitive would not fail (meaning it should set the var itself), and the fallback code gets executed only on VMs that do not have the prim. It should purely be an optimization, if possible. This is a pretty infrequent operation for the active process so the fallback code doesn't have to be highly efficient. I'd imagine waiting on an already signaled semaphore would do it? Or is that a no-op? |
I believe waiting on an already signalled semaphore is essentially a
no-op.
What I have found effective, though very hacky is to signal the
TimerSemaphore.
As the timer process has the highest priority, it will immediately take
over.
The timer process will finish quickly and then wait on its semaphore
again, which then causes a full scheduling, which solves the issue.
Not a clean solution, but backwards-compatible with old VMs, so it
should only serve as a fallback.
It's important to do this **after** setting the priority instance
variable.
Cheers,
Leon
…On Thu, 2024-03-28 at 17:05 -0700, Vanessa Freudenberg via Vm-dev wrote:
> That sounds nice and simple. I'll go with that. The primitive can
> check
> for a runnable process simply:
> *
> the active process has no myList
> *
> a quiescent process (runnable but not the running one) has as
> its myList
> the list in the quiescentProcesseLists array indexed by its
> priority.
> So if neither of these is true the primitive can fail, and the
> fall-through
> code can set the inst var.
I'd prefer if the primitive would not fail (meaning it should set the
var itself), and the fallback code gets executed only on VMs that do
not have the prim. It should purely be an optimization, if possible.
This is a pretty infrequent operation for the active process so the
fallback code doesn't have to be highly efficient. I'd imagine
waiting on an already signaled semaphore would do it? Or is that a
no-op?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID:
***@***.***>
|
Aha. So (Btw: The timestamps of Yes, it would be nice to expose Delay class >> wakeHighestPriority
"Helper to fix scheduling after the active process changed its own priority."
TimingSemaphore signal.
Process >> priority: anInteger
"Set the receiver's priority to anInteger."
(anInteger >= Processor lowestPriority and:[anInteger <= Processor highestPriority])
ifTrue: [priority := anInteger. Delay wakeHighestPriority]
ifFalse: [self error: 'Invalid priority: ', anInteger printString]. Any concerns? |
This sounds reasonable except the comment in Delay implies it only is used for the active process. We need to decide on the exact semantics, and enforce them in the priority setter:
That's the ones I can think of off the cuff. |
If a process runs alone at its original priority and bumps it higher temporarily, setting it back and yielding will not schedule processes above its original priority. Only if there are other processes running on that original (lower) priority.
This seems to be an older optimization in
primitiveYield
.Here is an example:
Expected transcript output:
However, we get:
It is only circumstantial that P2 finishes at all because the Timer Interrupt Scheduler (80) will be signaled eventually and then trigger P2 (50) finally. But P1 (45) has finished by then. This is not fair.
We can show that it works as expected once another process works on the original priority (45):
The output is as expected:
By skipping the P3 output, we get the expected order for P1 and P2:
The optimization in
primitiveYield
reads:And so
wakeHighestPriority
will not be called in time. But I think we should support temporal priority bumping this way.The text was updated successfully, but these errors were encountered: