by simplegeek on 1/14/25, 1:23 PM with 24 comments
by colonCapitalDee on 1/18/25, 6:30 AM
P1 and P2 start executing. P1 sets temp=1, then P2 runs through the loop for i=1..9. Then P1 sets n=temp=1. P2 sets temp=2, then P1 resumes executing for i=2..10, and completes. P2 sets n=temp=2, then completes.
The intuition is P1 checkpoints, P2 runs through the loop up until the last iteration, P1 resets n to the checkpoint + 1, P2 checkpoints, P1 runs through the loop, then P2 resets n to the checkpoint + 1.
by tombert on 1/18/25, 2:50 AM
EXTENDS Naturals, Sequences
(*--algorithm StateStore {
variables
n = 0; completions = <<>>;
define {
Invar == Len(completions) = 2 => n # 2
}
fair process (thing \in {"p", "q"})
variables i = 0, temp = 0;
{
Loop:
while (i < 10) {
First:
temp := n + 1;
Second:
n := temp;
Last:
i := i + 1;
};
Complete:
completions := Append(completions, 1)
}
}*)
(I acknowledge that this isn't the most elegant Pluscal but I think it is a roughly accurate?)by Groxx on 1/18/25, 2:39 AM
>If we run P and Q concurrently, with ānā initialized to zero, what would the value of ānā be when the two processes finish executing their statements?
It depends a lot on the observer of `n` and what relationship it has with P and Q. Which isn't defined.
E.g. a trivial boundary-answer is that it can be 0, if nothing guarantees that P's and Q's threads' memory reaches the `n`-observer's thread. This is somewhat common if you try to synchronize via `sleep`, because that usually doesn't guarantee anything as all.
We also don't know the computer architecture. We can probably assume at least one byte moves between memory levels atomically, because basically every practical system does that, but that doesn't have to be true. If bits move between memory levels independently, this could observe 31, because it can be any combination of the bits between `00000` and `10100`, which includes `01011` -> there can be a `1` in any position, including all positions, so you can observe a number that was never assigned. (IRL: multi-word values and partial initializations can do this, e.g. it's why double-checked locking is flawed without something to guarantee initialization completes before the pointer is exposed)
by fjfaase on 1/15/25, 6:19 AM
I think it is possible to implement locking with only atomic assigments.
by hedin_hiervard on 1/18/25, 9:36 AM
by sim7c00 on 1/18/25, 7:19 PM
this will help to determine or realize better when and where synchronization is needed even though you might not expect it. (or remoddeling of the code).
its extremely hard to writr concurrent code well. i think i've hardly ever managed lockless code that wasnt super bugy (yet! :D). it takes a lot of focus and patience, and tons details about the platform(s) it might run on.
by chozang on 1/19/25, 8:34 PM
by jpc0 on 1/18/25, 1:15 PM
by Izikiel43 on 1/18/25, 1:51 AM
by dtgriscom on 1/18/25, 2:44 AM
(Assumes atomic assignments, as noted by someone else.)