tm1.c revision 436e89c602e787e7a27dd6624b09beed41a0da8a
1
2#include <stdio.h>
3#include <stdlib.h>
4
5/* An ultra-lame test program for RTM support, as available
6   on Haswell CPUs. */
7
8/* Attempt to run f(arg) as a transaction, and return a Boolean
9   indicating success or otherwise. */
10
11__attribute__((noinline))
12static int transactionally_apply ( void(*f)(void*), void* arg )
13{
14  register int ok;
15  __asm__ __volatile__(
16     "  xbegin .Lzzqqfail" );
17  f(arg);
18  __asm__ __volatile__(
19     /* This is a bit tricky.  If the transaction succeeds, control
20        will flow to this point.  If it fails, control continues at
21        .Lzzqqfail, with the machine state looking the same as it did
22        immediately before the xbegin was executed. */
23     "  xend           \n\t"  /* declare the transaction to be complete */
24     "  movl $1,%0     \n\t"  /* "ok = 1" */
25     "  jmp .Lzzqqout  \n\t"  /* jump to the merge point */
26     ".Lzzqqfail:      \n\t"  /* it failed .. */
27     "  movl $0,%0     \n\t"  /* "ok = 0" */
28     ".Lzzqqout:       \n\t"  /* this is the merge point */
29     : "=r"(ok) : : "cc", "rax"
30  );
31  return ok;
32}
33
34void testfn ( void* arg )
35{
36}
37
38int main ( void )
39{
40  long long int ok = transactionally_apply ( testfn, NULL );
41  printf("transactionally_apply: ok = %lld (expected %d)\n", ok, 0);
42
43  __asm__ __volatile__(
44    "movq $0, %%rax  \n\t"
45    "xtest           \n\t"
46    "setz %%al       \n\t"
47    "movq %%rax, %0  \n\t"
48    : "=r"(ok) : : "cc","rax"
49  );
50  printf("xtest: rflags.Z = %lld (expected %d)\n", ok, 1);
51
52  /*
53  printf("testing XACQUIRE / XRELEASE\n");
54  int n = 0;
55  __asm__ __volatile__(
56     "xacquire lock incl (%0)   \n\t"
57     "xrelease lock decl (%0)   \n\t"
58     : : "r"(&n) : "cc", "memory"
59  );
60  */
61
62  __asm__ __volatile__( "xabort $0x1" );
63  printf("xabort: outside transaction is nop.\n");
64
65  return 0;
66}
67