NO

Author Topic: atomic operation question  (Read 4984 times)

Xsoda

  • Guest
atomic operation question
« 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:
Code: [Select]
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!
« Last Edit: January 09, 2013, 06:26:34 AM by Xsoda »

Offline jj2007

  • Member
  • *
  • Posts: 536

CommonTater

  • Guest
Re: atomic operation question
« Reply #2 on: January 09, 2013, 02:44:21 PM »
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:
Code: [Select]
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.
« Last Edit: January 09, 2013, 02:54:16 PM by CommonTater »


Offline jj2007

  • Member
  • *
  • Posts: 536
Re: atomic operation question
« Reply #4 on: January 10, 2013, 02:18:40 PM »
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

  • Guest
Re: atomic operation question
« Reply #5 on: January 10, 2013, 05:47:59 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.
 
 
 
 
« Last Edit: January 10, 2013, 11:32:20 PM by CommonTater »

Xsoda

  • Guest
Re: atomic operation question
« Reply #6 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.

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

Code: [Select]
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;
}
« Last Edit: January 11, 2013, 02:53:43 AM by Xsoda »

CommonTater

  • Guest
Re: atomic operation question
« Reply #7 on: January 11, 2013, 09:12:58 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 ... 

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: atomic operation question
« Reply #8 on: January 11, 2013, 10:08:45 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