/[pcsx2_0.9.7]/trunk/common/include/Utilities/TlsVariable.inl
ViewVC logotype

Contents of /trunk/common/include/Utilities/TlsVariable.inl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations) (download)
Mon Sep 6 11:40:06 2010 UTC (9 years, 5 months ago) by william
File size: 3980 byte(s)
exported r3113 from ./upstream/trunk
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 #include "Threading.h"
19
20 #if PCSX2_THREAD_LOCAL
21 # define DeclareTls(x) __threadlocal x
22 #else
23 # define DeclareTls(x) Threading::TlsVariable<x>
24 #endif
25
26 namespace Threading
27 {
28 // --------------------------------------------------------------------------------------
29 // TlsVariable - Thread local storage
30 // --------------------------------------------------------------------------------------
31 // Wrapper class for pthread_getspecific, which is pthreads language for "thread local
32 // storage." This class enables code to act as a drop-in replacement for compiler-native
33 // thread local storage (typically specified via __threadlocal). Mac OS/X (Darwin) does
34 // not have TLS, which is the main reason for this class existing.
35 //
36 // Performance considerations: While certainly convenient, performance of this class can
37 // be sub-optimal when the operator overloads are used, since each one will most likely
38 // result in repeated calls to pthread_getspecific. (if the function inlines then it
39 // should actually optimize well enough, but I doubt it does).
40 //
41 template< typename T >
42 class TlsVariable
43 {
44 DeclareNoncopyableObject(TlsVariable);
45
46 protected:
47 pthread_key_t m_thread_key;
48 T m_initval;
49
50 public:
51 TlsVariable();
52 TlsVariable( T initval );
53
54 virtual ~TlsVariable() throw();
55 T* GetPtr() const;
56 T& GetRef() const { return *GetPtr(); }
57
58 TlsVariable& operator=( const T& src )
59 {
60 GetRef() = src;
61 return *this;
62 }
63
64 bool operator==( const T& src ) const { return GetRef() == src; }
65 bool operator!=( const T& src ) const { return GetRef() != src; }
66 bool operator>( const T& src ) const { return GetRef() > src; }
67 bool operator<( const T& src ) const { return GetRef() < src; }
68 bool operator>=( const T& src ) const { return GetRef() >= src; }
69 bool operator<=( const T& src ) const { return GetRef() <= src; }
70
71 T operator+( const T& src ) const { return GetRef() + src; }
72 T operator-( const T& src ) const { return GetRef() - src; }
73
74 void operator+=( const T& src ) { GetRef() += src; }
75 void operator-=( const T& src ) { GetRef() -= src; }
76
77 operator T&() const { return GetRef(); }
78
79 protected:
80 void CreateKey();
81 };
82 };
83
84 template< typename T >
85 Threading::TlsVariable<T>::TlsVariable()
86 {
87 CreateKey();
88 }
89
90 template< typename T >
91 Threading::TlsVariable<T>::TlsVariable( T initval )
92 {
93 CreateKey();
94 m_initval = initval;
95 }
96
97 template< typename T >
98 Threading::TlsVariable<T>::~TlsVariable() throw()
99 {
100 if( m_thread_key != NULL )
101 pthread_key_delete( m_thread_key );
102 }
103
104 template< typename T >
105 T* Threading::TlsVariable<T>::GetPtr() const
106 {
107 T* result = (T*)pthread_getspecific( m_thread_key );
108 if( result == NULL )
109 {
110 pthread_setspecific( m_thread_key, result = (T*)_aligned_malloc( sizeof(T), 16 ) );
111 if( result == NULL )
112 throw Exception::OutOfMemory( "Out of memory allocating thread local storage variable." );
113 *result = m_initval;
114 }
115 return result;
116 }
117
118 template< typename T >
119 void Threading::TlsVariable<T>::CreateKey()
120 {
121 if( 0 != pthread_key_create(&m_thread_key, _aligned_free) )
122 {
123 pxFailRel( "Thread Local Storage Error: key creation failed." );
124 }
125 }

  ViewVC Help
Powered by ViewVC 1.1.22