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