atomic operation question

Started by Xsoda, January 09, 2013, 06:13:52 AM

Previous topic - Next topic

Xsoda

I use the atomic_compare_exchange_strong in atomic.h of c11.
but it report an error.
Quote
POLINK: error: Unresolved external symbol '___atomic_compare_exchange64_strong_explicit'.
POLINK: fatal error: 1 unresolved external(s).

the code:

unsigned long long *a, b, c;
// some code
atomic_compare_exchange_strong(a, b, c);


and, if i used unsigned long replaced and there NO this problem!


CommonTater

#2
Quote from: Xsoda on January 09, 2013, 06:13:52 AM
I use the atomic_compare_exchange_strong in atomic.h of c11.
but it report an error.
Quote
POLINK: error: Unresolved external symbol '___atomic_compare_exchange64_strong_explicit'.
POLINK: fatal error: 1 unresolved external(s).

the code:

unsigned long long *a, b, c;
// some code
atomic_compare_exchange_strong(a, b, c);


and, if i used unsigned long replaced and there NO this problem!

Make sure you #include <stdatomic.h> in your source page.
These are _cdecl functions. Check the calling convention setting in your project options.

Also check the help file ... put your cursor on the highlighted function name and press F1 (Pelles C has one of the best help files going).   I believe you will find that the first two parameters to the function need to be pointers...

Finally, there is the possibility this is a bug... try it with other types unsigned long, unsigned short, etc.  If only the unsigned long long type gives you problems, you should report it in the Bug Reports forum.


jj2007

Sorry, I thought it was obvious.

C++, Kernel32:
LONG __cdecl InterlockedCompareExchange(
  _Inout_  LONG volatile *Destination,
  _In_     LONG Exchange,
  _In_     LONG Comparand
);

C++, Kernel64:
LONGLONG __cdecl InterlockedCompareExchange64(
  _Inout_  LONGLONG volatile *Destination,
  _In_     LONGLONG Exchange,
  _In_     LONGLONG Comparand
);

Kernel32 disassembled:
        762FC37C    8B4C24 04            mov ecx, [esp+4]
        762FC380    8B5424 08            mov edx, [esp+8]
        762FC384    8B4424 0C            mov eax, [esp+0C]
        762FC388    F0:0FB111            lock cmpxchg [ecx], edx


Assembler logic:
        if eax=Dest
                mov Dest, edx
        else
                mov eax, Dest
        endif

Assembler, direct:
        mov Dest11, 11
        mov edx, 22
        mov eax, 33
        lock cmpxchg Dest11, edx

Assembler, via Kernel32:
        mov Dest11, 11
        invoke InterlockedCompareExchange, addr Dest11, 22, 33

Right now I can't check how the 64-bit version is implemented, but you can google for CMPXCHG8B CMPXCHGQ (they look similar but are not identical).

CommonTater

#5
Quote from: jj2007 on January 10, 2013, 02:18:40 PM
Sorry, I thought it was obvious.

JJ ... this is a beginner.  He's not going to be impressed with your ASM skills and an answer from C++ is not even relevent here... he's just going to be confused.

He needs to know how to get the Pelles C function working... If you can't help him with Pelles C, you're not helping him.




Xsoda

#6
Thanks very much, and ___atomic_compare_exchange64_strong_explicit not in Pelles c 's static lib file. becuse this is a linker error.

jj2007, thank you. your reply is welcome. I write a cas function on basis of stackoverflow's question.


static inline unsigned int compare_and_swap(volatile unsigned long long *mem,
volatile unsigned long long old,
volatile unsigned long long _new)
{
char result;
__asm {
push edi
mov esi, mem
lea edi, _new
mov ebx, [edi]
mov ecx, [edi + 4]
lea edi, old
mov eax, [edi]
mov edx, [edi + 4]
lock cmpxchg8b qword ptr [esi]
setz bl
mov result, bl
pop edi
}
return (int)result;
}

CommonTater

Quote from: Xsoda on January 11, 2013, 02:50:46 AM
Thanks very much, and ___atomic_compare_exchange64_strong_explicit not in Pelles c 's static lib file. becuse this is a linker error.

Then you should post this to the Bug Reports forum ... 

jj2007

Quote from: Xsoda on January 11, 2013, 02:50:46 AM
I write a cas function on basis of stackoverflow's question.

Great. For comparison, here the disassembly of InterlockedCompareExchange64 (it looks like a Win64 thing, but it's actually Kernel32)

RtlInterlockedCompareExchange64 (Win7-32)
77B45AEC        53                   push ebx
77B45AED        55                   push ebp
77B45AEE        8B6C24 0C            mov ebp, [esp+0C]
77B45AF2        8B5C24 10            mov ebx, [esp+10]
77B45AF6        8B4C24 14            mov ecx, [esp+14]
77B45AFA        8B4424 18            mov eax, [esp+18]
77B45AFE        8B5424 1C            mov edx, [esp+1C]
77B45B02        F0:0FC74D 00         lock cmpxchg8b [ebp]
77B45B07        5D                   pop ebp
77B45B08        5B                   pop ebx
77B45B09        C2 1400              retn 14