cosmopolitan/libc/intrin/cmpxchg.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

26 lines
1.3 KiB
C
Raw Normal View History

#ifndef COSMOPOLITAN_LIBC_INTRIN_CMPXCHG_H_
#define COSMOPOLITAN_LIBC_INTRIN_CMPXCHG_H_
2022-08-11 19:13:18 +00:00
#include "libc/intrin/asmflag.h"
COSMOPOLITAN_C_START_
2023-05-02 02:43:59 +00:00
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86__)
#define _cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \
({ \
2023-11-16 04:57:18 +00:00
bool32 DidIt; \
autotype(IFTHING) IfThing = (IFTHING); \
typeof(*IfThing) IsEqualToMe = (ISEQUALTOME); \
typeof(*IfThing) ReplaceItWithMe = (REPLACEITWITHME); \
asm volatile(ZFLAG_ASM("cmpxchg\t%3,%1") \
: ZFLAG_CONSTRAINT(DidIt), "+m"(*IfThing), "+a"(IsEqualToMe) \
: "r"(ReplaceItWithMe) \
: "cc"); \
DidIt; \
})
#else
#define _cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \
(*(IFTHING) == (ISEQUALTOME) ? (*(IFTHING) = (REPLACEITWITHME), 1) : 0)
#endif
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_INTRIN_CMPXCHG_H_ */