Created
September 21, 2013 23:20
-
-
Save alk/6655145 to your computer and use it in GitHub Desktop.
tsx test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
/* note: much of tsx code was stolen from glibc */ | |
/* Official RTM intrinsics interface matching gcc/icc, but works | |
on older gcc compatible compilers and binutils. | |
We should somehow detect if the compiler supports it, because | |
it may be able to generate slightly better code. */ | |
#define _XABORT_EXPLICIT (1 << 0) | |
#define _XABORT_RETRY (1 << 1) | |
#define _XABORT_CONFLICT (1 << 2) | |
#define _XABORT_CAPACITY (1 << 3) | |
#define _XABORT_DEBUG (1 << 4) | |
#define _XABORT_NESTED (1 << 5) | |
#define _XABORT_CODE(x) (((x) >> 24) & 0xff) | |
#define _XBEGIN_STARTED (~0u) | |
#define _ABORT_LOCK_BUSY 0xff | |
#define _ABORT_LOCK_IS_LOCKED 0xfe | |
#define _ABORT_NESTED_TRYLOCK 0xfd | |
#define __force_inline __attribute__((__always_inline__)) inline | |
#ifdef USE_TSX | |
static __force_inline int _xbegin(void) | |
{ | |
int ret = _XBEGIN_STARTED; | |
asm volatile (".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory"); | |
return ret; | |
} | |
static __force_inline void _xend(void) | |
{ | |
asm volatile (".byte 0x0f,0x01,0xd5" ::: "memory"); | |
} | |
static __force_inline void _xabort(const unsigned int status) | |
{ | |
asm volatile (".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory"); | |
} | |
static __force_inline int _xtest(void) | |
{ | |
unsigned char out; | |
asm volatile (".byte 0x0f,0x01,0xd6 ; setnz %0" : "=r" (out) :: "memory"); | |
return out; | |
} | |
#else | |
static __force_inline int _xbegin(void) | |
{ | |
int ret = _XBEGIN_STARTED; | |
return ret; | |
} | |
static __force_inline void _xend(void) | |
{ | |
} | |
static __force_inline void _xabort(const unsigned int status) | |
{ | |
abort(); | |
} | |
static volatile xtest_thing; | |
static __force_inline int _xtest(void) | |
{ | |
return !xtest_thing; | |
} | |
#endif | |
static volatile int some_location __attribute__((aligned(64))); | |
static volatile unsigned long long some_other_location __attribute__((aligned(64))); | |
static volatile unsigned int skips __attribute__((aligned(64))); | |
int main(void) | |
{ | |
unsigned int i; | |
unsigned int initial = (unsigned)(0x20000000); | |
for (i = initial; i>0; i--) { | |
int status; | |
again: | |
status = _xbegin(); | |
/* | |
* if (status != _XBEGIN_STARTED) { | |
* skips++; | |
* goto again; | |
* } | |
*/ | |
if (!_xtest()) { | |
skips++; | |
if (skips == (unsigned)0xffff) { | |
abort(); | |
} | |
goto again; | |
} | |
if (status != _XBEGIN_STARTED) { | |
_xabort(_ABORT_LOCK_BUSY); | |
} | |
if (some_location != 0) | |
_xabort(_ABORT_LOCK_IS_LOCKED); | |
#ifdef USE_TSX | |
some_other_location++; | |
#else | |
{ | |
unsigned long long new_value = some_other_location + 1; | |
if (!__sync_bool_compare_and_swap(&some_other_location, new_value - 1, new_value)) { | |
abort(); | |
} | |
} | |
#endif | |
_xend(); | |
} | |
printf("skips: %u, total txns: %u\n", skips, initial); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment