OptiX  3.9
NVIDIA OptiX Acceleration Engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
Atom.h
1 
2 /*
3  * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
4  *
5  * NVIDIA Corporation and its licensors retain all intellectual property and proprietary
6  * rights in and to this software, related documentation and any modifications thereto.
7  * Any use, reproduction, disclosure or distribution of this software and related
8  * documentation without an express license agreement from NVIDIA Corporation is strictly
9  * prohibited.
10  *
11  * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
12  * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
13  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14  * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
15  * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
16  * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
17  * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
18  * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
19  * SUCH DAMAGES
20  */
21 
22 #ifndef __optix_optix_prime_atom_h__
23 #define __optix_optix_prime_atom_h__
24 
25 #if defined(_MSC_VER)
26 # define PRIME_ATOM32_MSC
27 # include <math.h>
28 # include <intrin.h>
29 # pragma intrinsic (_InterlockedExchangeAdd)
30 # pragma intrinsic (_InterlockedCompareExchange)
31 #elif defined(__GNUC__) || defined(__ICC)
32 # define PRIME_ATOM32_GCC
33 #endif
34 
35 namespace optix {
36  namespace prime {
37 
39 
41  class Atom32
42  {
43  public:
45  Atom32(const unsigned int val) : m_atom(val) {}
46 
48  unsigned int operator++();
49 
51  unsigned int operator--();
52 
53  private:
54  volatile unsigned int m_atom;
55  };
56 
57 #if defined(PRIME_ATOM32_MSC)
58 
59  //
60  // operator++
61  //
62  inline unsigned int Atom32::operator++() {
63  return _InterlockedExchangeAdd(reinterpret_cast<volatile long *>(&m_atom),1L) + 1L;
64  }
65 
66  //
67  // operator--
68  //
69  inline unsigned int Atom32::operator--() {
70  return _InterlockedExchangeAdd(reinterpret_cast<volatile long *>(&m_atom),-1L) - 1L;
71  }
72 
73 #elif defined(PRIME_ATOM32_GCC) // defined(PRIME_ATOM32_X86MSC)
74 
75  //
76  // operator++
77  //
78  inline unsigned int Atom32::operator++() {
79  unsigned int retval;
80  asm volatile (
81  "movl $1,%0\n"
82  "lock; xaddl %0,%1\n"
83  "addl $1,%0\n"
84  : "=&r" (retval), "+m" (m_atom)
85  :
86  : "cc"
87  );
88  return retval;
89  }
90 
91  //
92  // operator--
93  //
94  inline unsigned int Atom32::operator--() {
95  unsigned int retval;
96  asm volatile (
97  "movl $-1,%0\n"
98  "lock; xaddl %0,%1\n"
99  "addl $-1,%0\n"
100  : "=&r" (retval), "+m" (m_atom)
101  :
102  : "cc"
103  );
104  return retval;
105  }
106 
107 #else
108 # error One of PRIME_ATOM32_X86MSC, PRIME_ATOM32_X86GCC must be defined.
109 #endif
110 
111 #undef PRIME_ATOM32_MSC
112 #undef PRIME_ATOM32_GCC
113 
115 
116  } // namespace prime
117 } // namespace optix
118 
119 #endif // #ifndef __optix_optix_prime_atom_h__