issue#11: cds: changed __CDS_ guard prefix to CDSLIB_ for all .h files
[libcds.git] / cds / threading / details / cxx11_manager.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_THREADING_DETAILS_CXX11_MANAGER_H
4 #define CDSLIB_THREADING_DETAILS_CXX11_MANAGER_H
5
6 #include <cds/threading/details/_common.h>
7
8 #ifndef CDS_CXX11_THREAD_LOCAL_SUPPORT
9 #   error "The compiler does not support C++11 thread_local keyword. You cannot use CDS_THREADING_CXX11 threading model."
10 #endif
11
12 //@cond
13 namespace cds { namespace threading {
14
15     //@cond
16     struct cxx11_internal {
17         typedef unsigned char  ThreadDataPlaceholder[ sizeof(ThreadData) ];
18         static thread_local ThreadDataPlaceholder CDS_DATA_ALIGNMENT(8) s_threadData;
19         static thread_local ThreadData * s_pThreadData;
20     };
21     //@endcond
22
23     /// cds::threading::Manager implementation based on c++11 thread_local declaration
24     CDS_CXX11_INLINE_NAMESPACE namespace cxx11 {
25
26         /// Thread-specific data manager based on c++11 thread_local feature
27         class Manager {
28         private :
29             //@cond
30
31             static ThreadData * _threadData()
32             {
33                 return cxx11_internal::s_pThreadData;
34             }
35
36             static ThreadData * create_thread_data()
37             {
38                 if ( !cxx11_internal::s_pThreadData ) {
39                     cxx11_internal::s_pThreadData = new (cxx11_internal::s_threadData) ThreadData();
40                 }
41                 return cxx11_internal::s_pThreadData;
42             }
43
44             static void destroy_thread_data()
45             {
46                 if ( cxx11_internal::s_pThreadData ) {
47                     ThreadData * p = cxx11_internal::s_pThreadData;
48                     cxx11_internal::s_pThreadData = nullptr;
49                     p->ThreadData::~ThreadData();
50                 }
51             }
52             //@endcond
53
54         public:
55             /// Initialize manager (empty function)
56             /**
57                 This function is automatically called by cds::Initialize
58             */
59             static void init()
60             {}
61
62             /// Terminate manager (empty function)
63             /**
64                 This function is automatically called by cds::Terminate
65             */
66             static void fini()
67             {}
68
69             /// Checks whether current thread is attached to \p libcds feature or not.
70             static bool isThreadAttached()
71             {
72                 return _threadData() != nullptr;
73             }
74
75             /// This method must be called in beginning of thread execution
76             static void attachThread()
77             {
78                 create_thread_data()->init();
79             }
80
81             /// This method must be called in end of thread execution
82             static void detachThread()
83             {
84                 assert( _threadData() );
85
86                 if ( _threadData()->fini() )
87                     destroy_thread_data();
88             }
89
90             /// Returns ThreadData pointer for the current thread
91             static ThreadData * thread_data()
92             {
93                 ThreadData * p = _threadData();
94                 assert( p );
95                 return p;
96             }
97
98             /// Get gc::HP thread GC implementation for current thread
99             /**
100                 The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution
101                 or if you did not use gc::HP.
102                 To initialize gc::HP GC you must constuct cds::gc::HP object in the beginning of your application
103             */
104             static gc::HP::thread_gc_impl&   getHZPGC()
105             {
106                 assert( _threadData()->m_hpManager != nullptr );
107                 return *(_threadData()->m_hpManager);
108             }
109
110             /// Get gc::DHP thread GC implementation for current thread
111             /**
112                 The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution
113                 or if you did not use gc::DHP.
114                 To initialize gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application
115             */
116             static gc::DHP::thread_gc_impl&   getDHPGC()
117             {
118                 assert( _threadData()->m_dhpManager != nullptr );
119                 return *(_threadData()->m_dhpManager);
120             }
121
122             //@cond
123             static size_t fake_current_processor()
124             {
125                 return _threadData()->fake_current_processor();
126             }
127             //@endcond
128         };
129
130     } // namespace cxx11
131
132 }} // namespace cds::threading
133 //@endcond
134
135 #endif // #ifndef CDSLIB_THREADING_DETAILS_CXX11_MANAGER_H