InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
IDThreading.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: Florin Trofin
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // ADOBE CONFIDENTIAL
16 //
17 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
18 //
19 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
20 // with the terms of the Adobe license agreement accompanying it. If you have received
21 // this file from a source other than Adobe, then your use, modification, or
22 // distribution of it requires the prior written permission of Adobe.
23 //
24 //========================================================================================
25 
26 
27 #ifndef __IDTHREADING__
28 #define __IDTHREADING__
29 
30 #include "IDThreadingPrimitives.h"
31 #include "OMTypes.h"
32 #include "K2Assert.h"
33 
34 namespace IDThreading
35 {
36  typedef uint32 ExecutionContextID;
37  extern RUNTIME_DECL const ExecutionContextID kInvalidExecutionContextID;
38 
43  RUNTIME_DECL ExecutionContextID CurrentExecutionContextId ();
44 
48  RUNTIME_DECL void SetThreadName(ThreadID id, const char* name);
49 
50  //****************************************************************************************
51 
56  RUNTIME_DECL void BeginPublicThreadBottleneck ();
57 
63  RUNTIME_DECL void EndPublicThreadBottleneck ();
64 
65  typedef uint32 PublicThreadLocalStorageKey;
66  typedef uint64 PublicThreadLocalStorageValue;
67 
68  RUNTIME_DECL PublicThreadLocalStorageKey PublicThreadLocalStorageAllocKey ();
69  RUNTIME_DECL void PublicThreadLocalStorageRealeaseKey(PublicThreadLocalStorageKey key);
70  RUNTIME_DECL void PublicThreadLocalStorageSet (PublicThreadLocalStorageKey key, PublicThreadLocalStorageValue value);
71  RUNTIME_DECL PublicThreadLocalStorageValue PublicThreadLocalStorageGet (PublicThreadLocalStorageKey key, PublicThreadLocalStorageValue initialVal);
72 
73  typedef uint32 PublicThreadLocalSmartPointerKey;
74  typedef boost::shared_ptr<void> PublicThreadLocalSmartPointerValue;
75 
76 
77  RUNTIME_DECL PublicThreadLocalSmartPointerKey PublicThreadLocalSmartPointerAllocKey ();
78  RUNTIME_DECL void PublicThreadLocalSmartPointerRealeaseKey(PublicThreadLocalSmartPointerKey key);
79  RUNTIME_DECL void PublicThreadLocalSmartPointerSet (PublicThreadLocalSmartPointerKey key, PublicThreadLocalSmartPointerValue value);
80  RUNTIME_DECL PublicThreadLocalSmartPointerValue PublicThreadLocalSmartPointerGet (PublicThreadLocalSmartPointerKey key);
81 
87  template<typename T>
88  class ThreadLocal : boost::noncopyable
89  {
90  public:
91 
92  explicit ThreadLocal (const T & initialVal) :
93  fKey (PublicThreadLocalStorageAllocKey ()),
94  fInitialVal(PublicThreadLocalStorageValue(CONVERSION_TO_THREADLOCALSTORAGE<T>::CONVERT(initialVal)))
95  {
96  }
97 
98  ~ThreadLocal ()
99  {
100  PublicThreadLocalStorageRealeaseKey(fKey);
101  }
102 
104  T Get () const
105  {
106  return T (PublicThreadLocalStorageGet (fKey, fInitialVal));
107  }
108 
110  void Set (T x)
111  {
112  PublicThreadLocalStorageValue value =
113  (PublicThreadLocalStorageValue) (CONVERSION_TO_THREADLOCALSTORAGE<T>::CONVERT(x));
114  PublicThreadLocalStorageSet (fKey, value);
115  }
116 
119  {
120  Set(x);
121  return *this;
122  }
123 
124  ThreadLocal<T>& operator +=(T x)
125  {
126  Set(Get() + x);
127  return *this;
128  }
129  ThreadLocal<T>& operator -=(T x)
130  {
131  Set(Get() - x);
132  return *this;
133  }
134  ThreadLocal<T>& operator ++()
135  {
136  return operator+=(1);
137  }
138  ThreadLocal<T>& operator --()
139  {
140  return operator-=(1);
141  }
142  private:
143  PublicThreadLocalStorageKey fKey;
144  PublicThreadLocalStorageValue fInitialVal;
145  };
146 
147 
154  template<typename T>
155  class ThreadLocalManagedObject : boost::noncopyable
156  {
157  public:
159  fKey (PublicThreadLocalSmartPointerAllocKey ()),
160  fInitialVal(nil)
161  {
162  }
163  ThreadLocalManagedObject(const T& intVal):
164  fKey (PublicThreadLocalSmartPointerAllocKey ()),
165  fInitialVal(new T(intVal))
166  {
167  }
168 
170  {
171  delete fInitialVal;
172  PublicThreadLocalSmartPointerRealeaseKey(fKey);
173  }
174  T *Get ()
175  {
176  return _get ();
177  }
178 
179  const T *Get () const
180  {
181  return _get ();
182  }
183 
184  const T& GetReference () const
185  {
186  return *_get ();
187  }
188 
189  void Set (const T& val)
190  {
191  *_get () = val;
192  }
193 
194  void Reset ()
195  {
196  *_get () = T();
197  }
198  private:
199 
200  T *_get () const
201  {
202  PublicThreadLocalSmartPointerValue value =
203  PublicThreadLocalSmartPointerGet (fKey);
204  T *p = (T*) (value.get());
205 
206  if ( p == 0)
207  {
208  p = fInitialVal? new T(*fInitialVal) : new T;
209 
210  value =
211  (PublicThreadLocalSmartPointerValue) (p);
212  PublicThreadLocalSmartPointerSet (fKey, value);
213  }
214  return p;
215  }
216 
217  PublicThreadLocalSmartPointerKey fKey;
218  T* fInitialVal;
219 
220  };
221 
224  template<typename T>
225  class ThreadLocalManagedArray : boost::noncopyable
226  {
227  public:
228  ThreadLocalManagedArray(size_t __size):
229  fKey (PublicThreadLocalSmartPointerAllocKey ()),
230  fSize(__size)
231  {
232  }
233 
235  {
236  PublicThreadLocalSmartPointerRealeaseKey(fKey);
237  }
238 
239  T *Get ()
240  {
241  return _get ();
242  }
243 
244  const T *Get () const
245  {
246  return _get ();
247  }
248 
249 
250  T *begin ()
251  {
252  return _get ();
253  }
254 
255  const T *begin () const
256  {
257  return _get ();
258  }
259 
260  T *end ()
261  {
262  return _get () + fSize;
263  }
264 
265  const T *end () const
266  {
267  return _get () + fSize;
268  }
269 
270  size_t size () const
271  {
272  return fSize;
273  }
274 
275  private:
276  T *_get () const
277  {
278  PublicThreadLocalSmartPointerValue value =
279  PublicThreadLocalSmartPointerGet (fKey);
280  std::vector<T> *p = (std::vector<T> *) (value.get());
281 
282  if (p == 0)
283  {
284  p = new std::vector<T>(fSize);
285  value =
286  (PublicThreadLocalSmartPointerValue) (p);
287  PublicThreadLocalSmartPointerSet (fKey, value);
288  }
289 
290  return &(*p)[0];
291  }
292 
293  const size_t fSize;
294  PublicThreadLocalSmartPointerKey fKey;
295 
296  };
297 
298  // private testing use only
299  RUNTIME_DECL void TestHook ();
300 
303  template<typename T>
304  inline bool operator<(ThreadLocal<T> const& left, ThreadLocal<T> const& right)
305  {
306  return left.Get() < right.Get();
307  }
308 
309  template<typename T>
310  inline bool operator==(ThreadLocal<T> const& left, ThreadLocal<T> const& right)
311  {
312  return left.Get() == right.Get();
313  }
314 
315  template<typename T>
316  inline bool operator<(ThreadLocal<T> const& left, T right)
317  {
318  return left.Get() < right;
319  }
320 
321  template<typename T>
322  inline bool operator<(T left, ThreadLocal<T> const& right)
323  {
324  return left < right.Get();
325  }
326 
327  template<typename T>
328  inline bool operator==(ThreadLocal<T> const& left, T right)
329  {
330  return left.Get() == right;
331  }
332 
333  template<typename T>
334  inline bool operator==(T left, ThreadLocal<T> const& right)
335  {
336  return left == right.Get();
337  }
338 
339  template<typename T>
340  inline bool operator!=(ThreadLocal<T> const& left, T right)
341  {
342  return left.Get() != right;
343  }
344 
345  template<typename T>
346  inline bool operator!=(T left, ThreadLocal<T> const& right)
347  {
348  return left != right.Get();
349  }
350 
355  RUNTIME_DECL void Sleep( uint32 milliseconds );
356 
357 
360  struct adopt_lock_t {};
361  extern const adopt_lock_t adopt_lock;
362 
368  template <class Mutex>
370  {
371  public:
375  explicit lock_guard(Mutex& mx)
376  : fMutex(mx), fLocked(false)
377  {
378  lock();
379  }
380 
385  : fMutex(mx), fLocked(true)
386  {
387  }
388 
393  {
394  if (fLocked)
395  unlock();
396  }
397 
398  private:
399 
400  // This class is not copyable
401  lock_guard(const lock_guard&);
402  lock_guard& operator=(const lock_guard&);
403 
405  void lock()
406  {
407  ASSERT_MSG (!fLocked, "lock_guard::lock called on an already owned mutex!");
408  fMutex.lock();
409  fLocked = true;
410  }
411 
413  void unlock()
414  {
415  ASSERT_MSG (fLocked, "lock_guard::unlock called on a mutex we don't own!");
416  fMutex.unlock();
417  fLocked = false;
418  }
419 
421  bool is_locked() const { return fLocked; }
422 
423  Mutex& fMutex;
424  bool fLocked;
425  };
426 
427  class spin_mutex_impl;
432  class RUNTIME_DECL spin_mutex
433  {
434  public:
435  spin_mutex();
436 
437  ~spin_mutex();
438 
442  void lock();
443 
448  bool try_lock();
449 
453  void unlock();
454 
455  private:
456  // This class is not copyable
457  spin_mutex(const spin_mutex&);
458  spin_mutex& operator=(const spin_mutex&);
459 
460  spin_mutex_impl* fIsLocked;
461  };
462 
463 } //IDThreading
464 #endif // __IDTHREADING__