Re: basic_string CoW concurrency: typo in N2668, or very subtle point?
On 2 Jul., 23:14, Louis Semprini <lsempr...@hotmail.com> wrote:
Hello,
I have read ISO/IEC JTC1 SC22 WG21 N2668 (a revision of N2647, which
is a revision of N2534).
"Concurrency Modifications to Basic String"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2668.htm
N2668 corrects a few typos from the previous versions, but there is
still one paragraph left which has me stumped:
Can anyone explain the following claim from the paper:
|Thus the only real anomaly seems to be that creating the initial
|non-const reference invalidates previously generated const
|references. This anomaly has unfortunate consequences.
|Typically, when v offers "container thread safety", we can do
|
| #pragma omp parallel for
| for( size_t i = 0, n = v.size(); i < n; ++i ) {
| v[i] = 0;
| }
|
|However, for a basic_string v, we must insert v[0];
|before the pragma to render the code correct.
The code in the sample does not appear to include any const
references, only non-const references, so
1. in what way does the code demonstrate the anomaly?
2. why would inserting v[0] help anything, since it is just another
non-const reference?
The example is correct as intended, but the mentioned existence
of at least one reference to const string is implied. If such
a reference exists, the loop-code *needs* to call v[0], which
is a reference to non-const string (as you correctly recognized).
The reason for not showing this reference is the fact, that the
caller of this loop typically is not aware of their existence.
Assume this loop is part of some function:
void do_some_thing_parallel(std::string& v) {
[..] // No references to const, but anything else
#pragma omp parallel for
for( size_t i = 0, n = v.size(); i < n; ++i ) {
v[i] = 0;
}
[..]
}
Ideally any function should work, if the implemention
is only aware of the full function body. In a non-
reference-counted implementation the code is correct.
In a reference-counted one with COW it is not, because
the expression
v[0];
must be added at the beginning of the loop to ensure
that the other references perform the required
copy.
Is the code in error? Or is there some tricky secret const reference
that I am missing?
There is some secret, if the string implementation uses
COW.
Perhaps the authors meant to say "v[i] = v[0]" inside the loop?
Nope, the code is correct as written.
Though this would be an odd example as one thread would be setting
v[0] to itself.
Exactly.
Or perhaps the code _does_ demonstrate a problem with the string
design, but not a problem relating to const references? I could see
that in this scenario, when n threads simultaneously try to do the
first 'unsharing' operation, the library would need to have proper
thread coordination to assure that the first thread completed the
unsharing operation before other threads attempted to generate the non-
const reference. But that seems like an ordinary requirement and not
one related to this paper.
The problem is based on the string design (if COW) and this
implementation detail becomes user-visible by this example.
If the call of v[0] does not happen, proper invalidation
of other references to const string won't happen correctly.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]