Closed GoogleCodeExporter closed 9 years ago
Please attach test program. Otherwise it's very hard to help you to help us.
Original comment by alkondratenko
on 29 Sep 2013 at 2:43
Unfortunately, I cannot attach test program, because it is proprietary software
.
However I did some debugging and I can tell now that bug is somehow related to
Intel compiler optimization and tcmalloc, because problem occurs in
multithreaded program and exception does not happen when "volatile" qualifier
is added to "next" pointer within Span struct.
struct Span {
...
Span* volatile next; // Used when in link list
..
}
Hope this will help.
Original comment by zndmi...@gmail.com
on 2 Oct 2013 at 9:58
That's somewhat helpful but not too much.
Are you seeing it just with intel compiler ?
volatile seems to hint at compiler reordering load of next pointer before lock
is taken. And you're on windows where we're using msvc compiler intrinsic-s for
atomic ops. And _maybe_ (I'll have to double check that later) some those do
not imply barrier for compiler.
If you're sufficiently familiar with the subject I invite you to take a look at
Spinlock::Lock method and it's invocation of Acquire_CompareAndSwap (as
implemented on windows).
Another potential issue is stronger aliasing assumptions of intel compiler.
I.e. SLL_ methods are casting pointers in a way that appears to be strict
aliasing unsafe.
Original comment by alkondratenko
on 2 Oct 2013 at 10:34
I see that only with Intel compiler.
Actually after additional debugging I realized that it was a bug in Intel
Compiler 14.
Compiler incorrectly inserts the inlined FetchFromSpans() function within loop.
Original comment by zndmi...@gmail.com
on 12 Oct 2013 at 2:59
Closing then.
I think there's still a bit of mystery around barrier-ness of those compiler
intrinsics. I.e. if intel folks actually believe they're free to move code
around that call or not. And if their belief is fair.
Thanks for raising this again.
Original comment by alkondratenko
on 12 Oct 2013 at 9:31
The problems was not barrier-ness of compiler intrinsics in this case.
The bug was that Intel Compiler 14 optimizer moved check in FetchFromSpans()
if (tcmalloc::DLL_IsEmpty(&nonempty_)) return NULL;
out of this loop
while (result < N) {
void *t = FetchFromSpans(); <== Exception is here !
if (!t) break;
SLL_Push(&head, t);
result++;
}
while inlining FetchFromSpans() into the loop.
So that check is called only before first call to FetchFromSpans().
Exception occurs when FetchFromSpans() is called second time from a loop when
nonempty list is already empty and this is not checked because
DLL_IsEmpty(&nonempty_) is not called.
Hope this clarifies a bit mistery with this case.
Original comment by zndmi...@gmail.com
on 21 Oct 2013 at 11:27
Original issue reported on code.google.com by
zndmi...@gmail.com
on 26 Sep 2013 at 10:20