Python 2.3 in testing
Martin v. Löwis
martin@v.loewis.de
Sun Apr 27 21:11:00 GMT 2003
Matthias Klose <doko@cs.tu-berlin.de> writes:
> Btw, koenntest Du Dir mal den Vorschlag von Loren ansehen bzw. auf
> einer Mehrprozessormachine (falls Du sowas hast) testen?
> http://gcc.gnu.org/ml/libstdc++/2003-04/msg00407.html
Hab' gerade (vor zwei Wochen) frisch eine bekommen :-)
[I started answering in German, but now I see that it might be more
productive to send this in English to Loren as well]
This code looks incorrect. When I try to compile
struct X{
_Atomic_word a;
};
void foo(struct X* s)
{
__atomic_add(&s->a, 10);
}
I get
_Z3fooP1X:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
.L2:
movl _ZZ18__exchange_and_addPViiE6__lock, %eax
#APP
xchgl %eax,_ZZ18__exchange_and_addPViiE6__lock
#NO_APP
testl %eax, %eax
jne .L2
movl (%edx), %eax
movl (%edx), %eax
addl $10, %eax
movl %eax, (%edx)
popl %ebp
movl $0, _ZZ18__exchange_and_addPViiE6__lock
ret
If I understand the C code correctly, it tries to put the value 1 into
__lock, and then tries to get 0 out of it. If you get the 0, you hold
the spinlock.
In the assembler code, I see none of this: no 1, but instead it looks
like the value of __lock gets swapped with itself. Apparently, the
declaration of input registers went wrong, it probably should be
"0" (__tmp)
instead.
If that part is corrected, it seems to me that the answer to the
question "Why is this OK?" is straight forward: We are holding the
lock, so we can release it by just assigning to it. It *may* be
necessary to put the 0 back in using an xchgl as well, but it appears
to me that this should happen atomically anyway - can a memory write
ever be partial on that architecture? Can it if the target address is
aligned?
I'm not quite sure what problem this is going to solve, though, for
Debian: There is an ABI change where, on i386, one needs to hold
__lock to perform the atomic add. This poses two questions
1. Where is __lock expected to live? Currently, it gets into all
object files, so it would always be present. Due to the nature
of symbol resolution, you might end up with multiple copies of
__lock, though, under obscure circumstances.
If it is supposed to live in libstdc++: How would binaries built
against this version of the ABI run on installations that assume
486+? where the variable is not present in libstdc++?
2. What happens if you mix i386 and i486+ ABI in a single program? It
appears to me that the following sequence of actions might be
possible, if two threads simultaneously try to modify the same
_Atomic_word, one with the i386 ABI, and one with the i486 ABI:
a) i386 obtains __lock
b) i386 reads value of __mem into __result
c) i386 reads value of __mem for addition
d) i486 performs atomic addition, giving __mem+486
e) i386 performs addition, and writes back __mem+386
f) i386 releases __lock
g) both return __mem
As a result, the variable is now __mem+386, whereas it should
be __mem+386+486, so the write operation of i486 was lost.
Regards,
Martin
More information about the Libstdc++
mailing list