File: CheckAtomicOps.cmake

package info (click to toggle)
openscenegraph 3.0.1-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 30,940 kB
  • sloc: cpp: 352,623; ansic: 9,043; java: 1,020; yacc: 548; objc: 417; makefile: 285; xml: 155; lex: 151
file content (137 lines) | stat: -rw-r--r-- 3,628 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# Check for availability of atomic operations 
# This module defines
# OPENTHREADS_HAVE_ATOMIC_OPS

OPTION(OPENTHREADS_ATOMIC_USE_MUTEX "Set to ON to force OpenThreads to use a mutex for Atmoic." OFF)

IF (OPENTHREADS_ATOMIC_USE_MUTEX)

    SET(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS 0)
    SET(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS 0)
    SET(_OPENTHREADS_ATOMIC_USE_SUN 0)
    SET(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED 0)
    SET(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC 0)

    SET(_OPENTHREADS_ATOMIC_USE_MUTEX 1)

ELSE()

    INCLUDE(CheckCXXSourceRuns)

    # Do step by step checking,
    CHECK_CXX_SOURCE_RUNS("
    #include <cstdlib>

    int main()
    {
       unsigned value = 0;
       void* ptr = &value;
       __sync_add_and_fetch(&value, 1);
       __sync_synchronize();
       __sync_sub_and_fetch(&value, 1);
       if (!__sync_bool_compare_and_swap(&value, 0, 1))
          return EXIT_FAILURE;

       if (!__sync_bool_compare_and_swap(&ptr, ptr, ptr))
          return EXIT_FAILURE;

       return EXIT_SUCCESS;
    }
    " _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)

    CHECK_CXX_SOURCE_RUNS("
    #include <stdlib.h>

    int main(int, const char**)
    {
       unsigned value = 0;
       void* ptr = &value;
       __add_and_fetch(&value, 1);
       __synchronize(value);
       __sub_and_fetch(&value, 1);
       if (!__compare_and_swap(&value, 0, 1))
          return EXIT_FAILURE;

       if (!__compare_and_swap((unsigned long*)&ptr, (unsigned long)ptr, (unsigned long)ptr))
          return EXIT_FAILURE;

       return EXIT_SUCCESS;
    }
    " _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)

    CHECK_CXX_SOURCE_RUNS("
    #include <atomic.h>
    #include <cstdlib>

    int main(int, const char**)
    {
       uint_t value = 0;
       void* ptr = &value;
       atomic_inc_uint_nv(&value);
       membar_consumer();
       atomic_dec_uint_nv(&value);
       if (0 != atomic_cas_uint(&value, 0, 1))
          return EXIT_FAILURE;

       if (ptr != atomic_cas_ptr(&ptr, ptr, ptr))
          return EXIT_FAILURE;

       return EXIT_SUCCESS;
    }
    " _OPENTHREADS_ATOMIC_USE_SUN)

    CHECK_CXX_SOURCE_RUNS("
    #include <windows.h>
    #include <intrin.h>
    #include <cstdlib>

    #pragma intrinsic(_InterlockedAnd)
    #pragma intrinsic(_InterlockedOr)
    #pragma intrinsic(_InterlockedXor)

    int main(int, const char**)
    {
       volatile long value = 0;
       long data = 0;
       long* volatile ptr = &data;

       InterlockedIncrement(&value);
       MemoryBarrier();
       InterlockedDecrement(&value);

       if (0 != InterlockedCompareExchange(&value, 1, 0))
          return EXIT_FAILURE;

       if (ptr != InterlockedCompareExchangePointer((PVOID volatile*)&ptr, (PVOID)ptr, (PVOID)ptr))
          return EXIT_FAILURE;

       return EXIT_SUCCESS;
    }
    " _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)

    CHECK_CXX_SOURCE_RUNS("
    #include <libkern/OSAtomic.h>

    int main()
    {
      volatile int32_t value = 0;
      long data = 0;
      long * volatile ptr = &data;

      OSAtomicIncrement32(&value);
      OSMemoryBarrier();
      OSAtomicDecrement32(&value);
      OSAtomicCompareAndSwapInt(value, 1, &value);
      OSAtomicCompareAndSwapPtr(ptr, ptr, (void * volatile *)&ptr);
    }
    " _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)

    IF(NOT _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS AND
       NOT _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS AND
       NOT _OPENTHREADS_ATOMIC_USE_SUN AND
       NOT _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED AND
       NOT _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
               SET(_OPENTHREADS_ATOMIC_USE_MUTEX 1)
    ENDIF()

ENDIF()