Low-Lock Singletons In D

Dmitry Olshansky dmitry.olsh at gmail.com
Mon May 6 11:56:00 PDT 2013


06-May-2013 22:23, Mehrdad пишет:
> On Monday, 6 May 2013 at 11:21:37 UTC, Dmitry Olshansky wrote:
>> Yes, but the 1st processor may read _static exactly when the 2nd is
>> inside the lock and writing to that field. Then chances are it will
>> read whatever partial state there is written.
>> Surely it can. 1st processor takes the lock and write while the second
>> one reads static_ to call Get.
>
>
> It's a single pointer, there is no partial state -- it's either written
> or it isn't.

True... e.g on x86 if that word is aligned.
But the core of problem is not only that word it's rather the fact
that processor (and compiler and who's not) is free to re-order 
read/write ops
inside that locked region.

Potentially it could lead to epically nasty things.

struct Static{
	int value;
	Static(int v){
		value = v;
	}
}

Now suppose:

lock(_static){
	_static = new Static(42); //or smth like
}

Is compiled down to this "C--" code (quite realistically):

lock _static_mutex;
x = alloc int;
x[0] = 42;
static_ = x;
unlock _static_mutex;

And now compiler/CPU decides to optimize/execute out of order (again, 
it's an illustration) it as:

lock _static_mutex;
x = alloc int;
//even if that's atomic
static_ = x;
// BOOM! somebody not locking mutex may already
// see static_ in "half-baked" state
x[0] = 42;
unlock _static_mutex;

Observe that:
a) It can and nothing prevents such a scenario. In fact it should feel 
free to optimize inside the locked section, but not accross
b) The chance that it happens is non-zero and rises with the complexity 
of construction
c) Depends on hardware kind(!) used as in OoO vs non-OoO

So it would work more reliably on old Atoms if that of any comfort ;). 
That if your compiler isn't equally smart and does nasty things behind 
your back ("Sorry, I just scheduled instructions optimally...").

>> One way is to ensure write is atomic w.r.t. that particular read
>> operation
>
>
> Are't pointer writes always atomic?

In short - no. Even not counting the world of legal re-ordering, 
unaligned writes too have this nasty habit of partially written stuff 
being visible at the wrong time.

Truth be told relying on these kind of "not ever likely to go wrong" is 
the very reason explicit atomics are encouraged even if they are NOPs on 
your current arch. That or faster/harder stuff - barriers.

Speaking of barriers - that is exactly the kind of thing that would 
disallow moving write of x[0] = 42 past "line" of static_ = x;
Simply put barriers act as a line of "no reordering across this point" 
for specific operations (depending on type, or all of them). Needles to 
say - hurts performance.

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list