Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

TBB library question atomic cmpxchg implementation

Greetings all,
I have some (minor) problems with the implementation of the above mentioned function in the library. Getting rid of the macro stuff, it reads like this:
[bash]static inline intXX_t cmpXchg(volPtr ptr, intXX_t dest, intXX_t compareTo)
    int32_t ans;
    __asm__ __volatile__("lock; cmpxchgBB %0, %1"
    		: "=a"(ans), "=m"(*(volInt32 *)ptr)			/* out */
    		: "0"(compareTo), "q"(dest), "m"(*(volInt32 *)ptr)	/* in */
    		: "memory");					        /* clobber */
    return ans;
where XX is either 32 or 64 and BB thus l or q, respectively.

My questions:
  1. How can the compiler (g++ tell whether 64bit R-registers (RDX, RAX, ...) or 32bit E-registers (EDX, EAX, ...) are used?
  2. cmpxchg8b (or cmpxchgl) potentially writes a result into EDX:EAX (equivalent setting for 16b variant);how will EDX and ECX be set in this implementation? All in all, why not use "b"(dest) instead of "q"(dest)? And: should we not mention "d" in the outlist, also?
  3. The assembler command changes the zeroflag, but the cobbler-list does NOT include "cc"- why?
Thanks a lot for help,
best wishes,
0 Kudos
2 Replies
1) Well, after doing some research, the only explanation I can see so far for NOT clobbering EBX, ECD or EDX and ZeroFlag seem to be that they are scratch or volatile registers. However, afaik this does NOT hold for EBX, so this implementation imho in the worst case suffers from undefined behaviour.

2) In Addition, I still have no idea how to tell between R- and E-registers. Some manuals say, that "r" references R-Registers, while "R" as a constraint refers to "E"-registers, but I can not really find any reliable resource or reference.

Thanks again for help,
0 Kudos

guess I figured out what the problem is. Refering to the file linux_intel64.h, I think the "q" case (that is the 64bit or 8byte Macro __MACHINE_DECL_ATOMICS(8,int64_t,"q") is not well defined, as it references a non existing assembler command:

the ordinary cmpxchg command to my knowledge is restricted to 8, 16 and 32 bit. For 64bit there is the alternative cmpxchg8b command. This does, however, NOT take two arguments and, as mentioned above, modifies registers, which the ordinary cmpxchg command does not doe (except for EAX).

I still think this flawed implementation, but lemme know if I am wrong.

Otherwise, consider this thread/ issue as solved.


0 Kudos