Re: Is this safe?
"Dragan Milenkovic" <dragan@plusplus.rs> wrote in message
news:h2hkro$2540$1@adenine.netfront.net...
[...]
If I understood correctly, you are saying that the _only_ thing that
is wrong with the original code is the possibility of using a register?
In order for the changes to be "visible" to all cores, there has to
be a matching memory barrier instruction _before_ reading a variable.
There is none before the first "if (!instance_)", so at that point
the core can "see" a non-null instance_, but can "see" *instance_
from the time before the constructor did its job. This is why
double-checked locking fails.
You generally need some kind of "acquire/load" barrier _after_ the load, and
"release/store" barrier before the _store_:
_______________________________________________________________
static int g_foo = 0;
static atomic_word g_finished = 0;
thread_1() {
g_foo = 1;
MEMBAR #StoreStore;
ATOMIC_STORE(&g_finished, 1);
}
thread_2() {
while (! ATOMIC_LOAD(&g_finished)) backoff();
MEMBAR #LoadLoad;
assert(g_foo == 1);
}
_______________________________________________________________
Also, DEC Alpha aside for a moment, you can take advantage of
data-dependencies, and skip the #LoadLoad altogether:
_______________________________________________________________
static int g_foo = 0
static int* g_pfoo = NULL;
thread_1() {
g_foo = 1;
MEMBAR #StoreStore;
ATOMIC_STORE_PTR(&g_pfoo, &g_foo);
}
thread_2() {
int* i;
while (! (i = ATOMIC_LOAD_PTR(&g_pfoo))) backoff();
assert(*i == 1);
}
_______________________________________________________________
BTW, all the examples above directly relate to DCL...
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]