Mallocator and 'shared'
Moritz Maxeiner via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Feb 12 19:15:26 PST 2017
On Monday, 13 February 2017 at 01:30:57 UTC, ag0aep6g wrote:
> This doesn't make sense to me. b depends on a. If I run thread
> 1 alone, I can expect b to be 1, no? Thread 2 can then a) read
> 0, write 1; or b) read 1, write 2. How can b be 0 when the
> writeln is executed?
>
> An example like this makes more sense to me:
>
> ----
> shared int a = 0, b = 0;
>
> // Thread 1:
> a = 1;
> b = 2;
>
> // Thread 2:
> writeln(a + b);
> ----
>
> One might think that thread 2 cannot print "2", because from
> the order of statements the numbers must be 0 + 0 or 1 + 0 or 1
> + 2. But thread 1 might execute `b = 2` before `a = 1`, because
> the order doesn't matter to thread 1. So 0 + 2 is possible, too.
You're right, of course, and I shall do well to remember not to
think up examples for non-sequential code at such an hour, I am
sorry. Thank you for providing a correct example plus
explanation. The rest of my post still stands, though.
In recompense I shall provide another example, this one
translated from Wikipedia[1] instead:
__gshared int f = 0, x = 0;
// thread 1
while (f == 0);
// Memory barrier required here
writeln(x)
// thread 2
x = 42;
// Memory barrier required here
f = 1;
The above demonstrates a case where you do need a memory barrier:
thread 1 and 2 have a consumer/producer relationship, where
thread 1 wants to consume a value from thread 2 via `x`, using
`f` to be notified that `x` is ready to be consumed;
Without memory barriers at both of the indicated lines the cpu is
free to reorder either thread:
The first is required so that thread 1 doesn't get reordered to
consume before being notified and the second so that thread 2
doesn't get reordered to signal thread 1 before having produced.
If we had made `f` and `x` `shared` instead of `__gshared` the
spec would require (at least) the two indicated memory barriers
being emitted. Currently, though, it won't and for this case
(AFAIK) `shared` won't get you any benefit I'm aware of over
`__gshared`. You'll still need to add those memory barriers
(probably using inline assembler, though I'm not sure what's the
best way is in D, since I usually just stick with message
passing).
[1] https://en.wikipedia.org/wiki/Memory_barrier
More information about the Digitalmars-d-learn
mailing list