InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
IDThreadingPrimitives.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: Florin Trofin
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
18 // with the terms of the Adobe license agreement accompanying it. If you have received
19 // this file from a source other than Adobe, then your use, modification, or
20 // distribution of it requires the prior written permission of Adobe.
21 //
22 //========================================================================================
23 
24 #ifndef __IDTHREADINGPRIMITIVES__
25 #define __IDTHREADINGPRIMITIVES__
26 
27 #include <boost/shared_ptr.hpp>
28 #include <boost/noncopyable.hpp>
29 #include <boost/static_assert.hpp>
30 #include <boost/mpl/or.hpp>
31 #include <boost/utility/enable_if.hpp>
32 #include <boost/type_traits.hpp>
33 #include <vector>
34 
35 #ifdef MACINTOSH
36 #include <pthread.h>
37 #include <libkern/OSAtomic.h>
38 #endif
39 
40 namespace IDThreading
41 {
46 #ifdef MACINTOSH
47  typedef pthread_t ThreadID;
48 #elif defined(WINDOWS)
49  typedef DWORD ThreadID;
50 #elif WASM
51  typedef int ThreadID;
52 #endif
53 
58  typedef ThreadID ThreadDomainID;
59 
60  // Invalid thread and thread domain IDs.
61  extern RUNTIME_DECL const ThreadID kInvalidThreadID;
62  extern RUNTIME_DECL const ThreadDomainID kInvalidThreadDomainID;
63 
69  RUNTIME_DECL ThreadID GetCurrentThreadId();
70 
82  RUNTIME_DECL ThreadDomainID GetCurrentThreadDomainId ();
83 
84 
89  RUNTIME_DECL bool IsMainThreadDomain();
90 
91 
94  RUNTIME_DECL uint32 GetHardwareConcurrency();
95 
96  // Discriminator for the size type for atomic operations
97  template <int s>
98  struct SizeType
99  {
100  enum { valueSize = s };
101  };
102 
103  template<size_t sizeInBytes>
105  {
106  template <typename T>
107  static T Increment(T& value);
108 
109  template <typename T>
110  static T Decrement(T& value);
111  };
112 
120  template<typename T>
121  typename boost::enable_if<boost::is_integral<T>, T>::type
122  AtomicIncrement(T& value)
123  {
124  // 32 or 64 bit values
125  BOOST_STATIC_ASSERT(sizeof(T) == 4 || sizeof(T) == 8);
126  return AtomicTraits<sizeof(T)>::Increment(value);
127  }
128 
136  template<typename T>
137  typename boost::enable_if<boost::is_integral<T>, T>::type
138  AtomicDecrement(T& value)
139  {
140  // 32 or 64 bit values
141  BOOST_STATIC_ASSERT(sizeof(T) == 4 || sizeof(T) == 8);
142  return AtomicTraits<sizeof(T)>::Decrement(value);
143  }
144 
145  // Implementations for the atomic operations
146  // Do not call these directly
147 #ifdef MACINTOSH
148 
149  template<>
150  struct AtomicTraits<4>
151  {
152  template <typename T>
153  static inline T Increment(T& value)
154  {
155  return ::OSAtomicIncrement32Barrier((int32_t*)(&value));
156  }
157 
158  template <typename T>
159  static inline T Decrement(T& value)
160  {
161  return ::OSAtomicDecrement32Barrier((int32_t*)(&value));
162  }
163  };
164 
165 #if defined(__ppc64__) || defined(__i386__) || defined(__x86_64__) || defined(__arm64__)
166 
167  template<>
168  struct AtomicTraits<8>
169  {
170  template <typename T>
171  static inline T Increment(T& value)
172  {
173  return ::OSAtomicIncrement64Barrier((int64_t*)(&value));
174  }
175 
176  template <typename T>
177  static inline T Decrement(T& value)
178  {
179  return ::OSAtomicDecrement64Barrier((int64_t*)(&value));
180  }
181  };
182 
183 #endif // defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)
184 
185 #elif defined(WINDOWS)
186 
187  template<>
188  struct AtomicTraits<4>
189  {
190  template <typename T>
191  static inline T Increment(T& value)
192  {
193  return ::InterlockedIncrement(reinterpret_cast<volatile long*>(&value));
194  }
195 
196  template <typename T>
197  static inline T Decrement(T& value)
198  {
199  return ::InterlockedDecrement(reinterpret_cast<volatile long*>(&value));
200  }
201  };
202 
203 
204  template<>
205  struct AtomicTraits<8>
206  {
207  template <typename T>
208  static inline T Increment(T& value)
209  {
210  return ::InterlockedIncrement64(reinterpret_cast<volatile long long*>(&value));
211  }
212 
213  template <typename T>
214  static inline T Decrement(T& value)
215  {
216  return ::InterlockedDecrement64(reinterpret_cast<volatile long long*>(&value));
217  }
218  };
219 
220 #endif // defined(WINDOWS)
221 
222 #ifdef WASM
223  template<>
224  struct AtomicTraits<4>
225  {
226  template <typename T>
227  static inline T Increment(T& value)
228  {
229  return ++value;
230  }
231 
232  template <typename T>
233  static inline T Decrement(T& value)
234  {
235  return --value;
236  }
237  };
238  template<>
239  struct AtomicTraits<8>
240  {
241  template <typename T>
242  static inline T Increment(T& value)
243  {
244  return ++value;
245  }
246 
247  template <typename T>
248  static inline T Decrement(T& value)
249  {
250  return --value;
251  }
252  };
253 #endif // WASM
254 
255 
256 } //IDThreading
257 #endif // __IDTHREADINGPRIMITIVES__