G
Salvete companeros,
irgendwie verzweifel ich just, weil ich eine atomare cmpxchg funktion zum Tauschen zweier Pointer implementieren wollte, die aber aus irgendwelchen Gründen nichts macht (core i7 Prozessor, sollte also von der Architektur her kein Problem sein). Hier mal mein Code, vielleicht hat ja jemand eine Idee. Habe es nach der Implementation auch mit beispielweise TBB von Intel verglichen und groß keine Unterschiede gefunden (außer den durch die Namen-Operatoren notwendigen wie der Verzicht auf die "m"-Constraint bei der outlist).
typedef struct { volatile void* ptr; } volPtr;
static inline void *atomicPtrCAS(volPtr *ptr, void *val1, void *cmpTo)
{
void *valOld
__asm__ __volatile__ ("lock ; cmpxchgl %[right],%[left]"
: "=a" (valOld)
: "0" (cmpTo), [right] "q" (val1), [left] "m" (ptr->ptr)
: "memory");
return valOld
}
und hier ein Beispielaufruf, der -- unter Einbindung von cstdint oder inttypes.h -- eigentlich die Pointer tauschen sollte....
int32_t *p4 = new int32_t;
int32_t *pb = new int32_t;
int32_t *ptmp = new int32_t;
volPtr tpb;
tpb.ptr = (void*)ptmp;
(*p4) = 25; (*pb) = 33;
atomicPtrCAS(&tpb, (void*)ptmp, (void*)pb);
Die Disassemblierung sieht eigentlich vernünftig aus, und beim cmpxchg-Befehl schreibt er auch einen neuen Wert in das eax-Register:
0x08048e83 <atomicPtrCAS+15>: mov -0x1c(%ebp),%eax
0x08048e86 <atomicPtrCAS+18>: mov -0x18(%ebp),%ecx
0x08048e89 <atomicPtrCAS+21>: mov -0x14(%ebp),%edx
0x08048e8c <atomicPtrCAS+24>: lock cmpxchg %ecx,(%edx)
0x08048e90 <atomicPtrCAS+28>: mov %eax,-0x4(%ebp)
0x08048e93 <atomicPtrCAS+31>: mov -0x4(%ebp),%eax
0x08048e96 <atomicPtrCAS+34>: leave
0x08048e97 <atomicPtrCAS+35>: ret
aber bei dem Rücksprung aus der Funktion sind alle Variablen bei alten Werten (obwohl ich ja pointer übergebe....).
Vermutlich ein einfacher, dummer Fehler, aber ich bin dankbar für Hilfe.
Beste Grüße,
gilgamash