CFx SDK Documentation 2026 SP0
Loading...
Searching...
No Matches
TrVisAtomics.h
Go to the documentation of this file.
1
2// Copyright (C) 2002-2024, Open Design Alliance (the "Alliance").
3// All rights reserved.
4//
5// This software and its documentation and related materials are owned by
6// the Alliance. The software may only be incorporated into application
7// programs owned by members of the Alliance, subject to a signed
8// Membership Agreement and Supplemental Software License Agreement with the
9// Alliance. The structure and organization of this software are the valuable
10// trade secrets of the Alliance and its suppliers. The software is also
11// protected by copyright law and international treaty provisions. Application
12// programs incorporating this software must include the following statement
13// with their copyright notices:
14//
15// This application incorporates Open Design Alliance software pursuant to a license
16// agreement with Open Design Alliance.
17// Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance.
18// All rights reserved.
19//
20// By use of this software, its documentation or related materials, you
21// acknowledge and accept the above terms.
23// Wrappers for atomic operations onto 16-bit integers
24
25#ifndef ODTRVIS16BITATOMICOPS
26#define ODTRVIS16BITATOMICOPS
27
28#include "OdMutex.h"
29
30#include "TD_PackPush.h"
31
33{
34#ifndef ARGSUSED
35#define ARGSUSED(x)
36#endif
37
38 // 32-bit atomic operations
39
40 // Increments incVal and returns incremented result value.
42 {
43#ifndef TD_SINGLE_THREAD
44 return (OdUInt32)::OdInterlockedIncrement(reinterpret_cast<volatile int*>(&incVal));
45#else // TD_SINGLE_THREAD
46 return ++incVal;
47#endif // TD_SINGLE_THREAD
48 }
49 // Decrements decVal and returns decremented result value.
51 {
52#ifndef TD_SINGLE_THREAD
53 return (OdUInt32)::OdInterlockedDecrement(reinterpret_cast<volatile int*>(&decVal));
54#else // TD_SINGLE_THREAD
55 return ++decVal;
56#endif // TD_SINGLE_THREAD
57 }
58 // Post-increment
60 { return interlockedIncrement32(incVal) - 1; }
61 // Post-decrement
63 { return interlockedDecrement32(decVal) + 1; }
64
65 // 16-bit atomic operations
66
67 // Increments incVal and returns incremented result value.
69 {
70#ifndef TD_SINGLE_THREAD
71#ifdef InterlockedIncrement16
72 ARGSUSED(refVal)
73 return InterlockedIncrement16(reinterpret_cast<volatile SHORT*>(&incVal));
74#else
75 if (&incVal < &refVal)
76 {
77 volatile int *pReg = reinterpret_cast<volatile int*>(&incVal);
78#ifdef ODA_BIGENDIAN
79 return (OdUInt16)(::OdInterlockedExchangeAdd(pReg, 1 << 16) >> 16) + 1;
80#else
81 return (OdUInt16)::OdInterlockedIncrement(pReg);
82#endif
83 }
84 else
85 {
86 volatile int *pReg = reinterpret_cast<volatile int*>(&refVal);
87#ifdef ODA_BIGENDIAN
88 return (OdUInt16)::OdInterlockedIncrement(pReg);
89#else
90 return (OdUInt16)(::OdInterlockedExchangeAdd(pReg, 1 << 16) >> 16) + 1;
91#endif
92 }
93#endif
94#else // TD_SINGLE_THREAD
95 ARGSUSED(refVal)
96 return ++incVal;
97#endif // TD_SINGLE_THREAD
98 }
99 // Decrements decVal and returns decremented result value.
101 {
102#ifndef TD_SINGLE_THREAD
103#ifdef InterlockedDecrement16
104 ARGSUSED(refVal)
105 return InterlockedDecrement16(reinterpret_cast<volatile SHORT*>(&decVal));
106#else
107 if (&decVal < &refVal)
108 {
109 volatile int *pReg = reinterpret_cast<volatile int*>(&decVal);
110#ifdef ODA_BIGENDIAN
111 return (OdUInt16)(::OdInterlockedExchangeAdd(pReg, -(1 << 16)) >> 16) - 1;
112#else
113 return (OdUInt16)::OdInterlockedDecrement(pReg);
114#endif
115 }
116 else
117 {
118 volatile int *pReg = reinterpret_cast<volatile int*>(&refVal);
119#ifdef ODA_BIGENDIAN
120 return (OdUInt16)::OdInterlockedDecrement(pReg);
121#else
122 return (OdUInt16)(::OdInterlockedExchangeAdd(pReg, -(1 << 16)) >> 16) - 1;
123#endif
124 }
125#endif
126#else // TD_SINGLE_THREAD
127 ARGSUSED(refVal)
128 return --decVal;
129#endif // TD_SINGLE_THREAD
130 }
131#undef ARGSUSED
132 // Post-increment
134 { return interlockedIncrement16(incVal, refVal) - 1; }
135 // Post-decrement
137 { return interlockedDecrement16(decVal, refVal) + 1; }
138} // namespace OdTrVisAtomics
139
140/*
141class tests
142{
143 struct A
144 {
145 OdUInt16 refCtr;
146 OdUInt16 flags;
147 A() { refCtr = 1; flags = 0xABCD; }
148 };
149 struct B
150 {
151 OdUInt16 flags;
152 OdUInt16 refCtr;
153 B() { refCtr = 1; flags = 0xABCD; }
154 };
155public:
156 tests()
157 {
158 A a; B b;
159 OdTrVisAtomics::interlockedIncrement16(a.refCtr, a.flags);
160 OdTrVisAtomics::interlockedIncrement16(b.refCtr, b.flags);
161 OdTrVisAtomics::interlockedDecrement16(a.refCtr, a.flags);
162 OdTrVisAtomics::interlockedDecrement16(b.refCtr, b.flags);
163 }
164} _tests;
165*/
166
167#include "TD_PackPop.h"
168
169#endif // ODTRVIS16BITATOMICOPS
unsigned int OdUInt32
unsigned short OdUInt16
#define ARGSUSED(x)
OdUInt16 interlockedPostIncrement16(OdUInt16 &incVal, OdUInt16 &refVal)
OdUInt16 interlockedDecrement16(OdUInt16 &decVal, OdUInt16 &refVal)
OdUInt32 interlockedIncrement32(OdUInt32 &incVal)
OdUInt16 interlockedIncrement16(OdUInt16 &incVal, OdUInt16 &refVal)
OdUInt32 interlockedDecrement32(OdUInt32 &decVal)
OdUInt16 interlockedPostDecrement16(OdUInt16 &decVal, OdUInt16 &refVal)
OdUInt32 interlockedPostIncrement32(OdUInt32 &incVal)
OdUInt32 interlockedPostDecrement32(OdUInt32 &decVal)