Zero  0.1.0
tls.h
Go to the documentation of this file.
1 /* -*- mode:C++; c-basic-offset:4 -*-
2  Shore-MT -- Multi-threaded port of the SHORE storage manager
3 
4  Copyright (c) 2007-2009
5  Data Intensive Applications and Systems Labaratory (DIAS)
6  Ecole Polytechnique Federale de Lausanne
7 
8  All Rights Reserved.
9 
10  Permission to use, copy, modify and distribute this software and
11  its documentation is hereby granted, provided that both the
12  copyright notice and this permission notice appear in all copies of
13  the software, derivative works or modified versions, and any
14  portions thereof, and that both notices appear in supporting
15  documentation.
16 
17  This code is distributed in the hope that it will be useful, but
18  WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
20  DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
21  RESULTING FROM THE USE OF THIS SOFTWARE.
22 */
23 
24 // -*- mode:c++; c-basic-offset:4 -*-
25 /*<std-header orig-src='shore' incl-file-exclusion='TLS_H'>
26 
27  $Id: tls.h,v 1.3 2010/06/23 23:42:57 nhall Exp $
28 
29 SHORE -- Scalable Heterogeneous Object REpository
30 
31 Copyright (c) 1994-99 Computer Sciences Department, University of
32  Wisconsin -- Madison
33 All Rights Reserved.
34 
35 Permission to use, copy, modify and distribute this software and its
36 documentation is hereby granted, provided that both the copyright
37 notice and this permission notice appear in all copies of the
38 software, derivative works or modified versions, and any portions
39 thereof, and that both notices appear in supporting documentation.
40 
41 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
42 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
43 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
44 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45 
46 This software was developed with support by the Advanced Research
47 Project Agency, ARPA order number 018 (formerly 8230), monitored by
48 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
49 Further funding for this work was provided by DARPA through
50 Rome Research Laboratory Contract No. F30602-97-2-0247.
51 
52 */
53 #ifndef __TLS_H
54 #define __TLS_H
55 
56 #include <pthread.h>
57 #include <new>
58 
83 namespace tls_tricks {
84 
106  class tls_manager {
107  public:
108  static void global_init();
109 
110  static void global_fini();
111 
112  static void register_tls(void (* init)(), void (* fini)());
113 
114  static void thread_init();
115 
116  static void thread_fini();
117 
118  static __thread bool _thread_initialized;
119  };
120 
134  }
135 
139  }
140  };
141 
143 
150  template<typename T>
151  struct tls_blob {
152  enum {
153  MAX_BYTES_NEEDED = sizeof(T) + sizeof(long) - 1,
154  ARRAY_SIZE = MAX_BYTES_NEEDED / sizeof(long)
155  };
156 
157  // force proper alignment...
158  long _reserved_space[ARRAY_SIZE];
159 
163  void init() {
164  new(get()) T;
165  }
166 
169  void fini() {
170  get()->~T();
171  }
172 
174  T* get() {
175  union {
176  long* a;
177  T* t;
178  } u = {_reserved_space};
179  return u.t;
180  }
181  };
182 
183 /* WARNING: These thread-local variables essentially use the namespace
184  of types, not variables for the purposes of detecting naming
185  collisions. So, just as the following two declarations could lead
186  to serious and hard-to-identify bugs:
187 
188  -- file1.cpp --
189  struct foo {
190  int a; int b;
191  };
192  -- file2.cpp --
193 
194  struct foo {
195  double a; char* b;
196  };
197 
198  So, too, would the following:
199 
200  -- file1.cpp --
201  DECLARE_TLS(foo, my_tls);
202  -- file2.cpp --
203  DECLARE_TLS(bar, my_tls);
204 
205  If you are lucky and the two types have different names the
206  compiler may notice, otherwise you're on your own.
207 */
208 
234 #define TLS_STRUCT(Type, Name, InitFn) \
235 struct Name { \
236  typedef tls_tricks::tls_blob< Type > Wrapper; \
237  Type &operator*() { return *get(); } \
238  Type* operator->() { return get(); } \
239  operator Type*() { return get(); } \
240  static Wrapper* get_wrapper() { \
241  static __thread Wrapper val; \
242  return &val; \
243  } \
244  static Type* get() { return get_wrapper()->get(); } \
245  static void init() { get_wrapper()->init(); } \
246  static void fini() { get_wrapper()->fini(); } \
247  InitFn() { \
248  static bool initialized = false; \
249  if(initialized) \
250  return; \
251  tls_tricks::tls_manager::register_tls(&init, &fini); \
252  initialized = true; \
253  } \
254 }
255 
256 
271 #define DECLARE_TLS(Type, Name) \
272  static \
273  TLS_STRUCT(Type, Name##_tls_wrapper, Name##_tls_wrapper) Name
274 
275 
292 #define DECLARE_TLS_SCHWARZ(Name) \
293  static struct Name##_tls_wrapper_schwarz { \
294  Name##_tls_wrapper_schwarz(); \
295  } Name##_schwarz
296 
305 #define DEFINE_TLS_SCHWARZ(Type, Name) \
306  static TLS_STRUCT(Type, Name##_tls_wrapper, static void init_wrapper) Name; \
307  Name##_tls_wrapper_schwarz::Name##_tls_wrapper_schwarz() { \
308  Name##_tls_wrapper::init_wrapper(); \
309  }
310 } /* namespace tls_tricks */
311 
312 #endif // __TLS_H
Wrapper for a type, used by TLS_STRUCT helper macro.
Definition: tls.h:151
static __thread bool _thread_initialized
Definition: tls.h:118
static void register_tls(void(*init)(), void(*fini)())
Definition: tls.cpp:93
static struct tls_manager_schwarz tlsm_schwarz_one_and_only
Definition: tls.h:142
static void thread_init()
Definition: tls.cpp:107
void init()
Definition: tls.h:163
~tls_manager_schwarz()
Destructor: invokes global init of all registered tls destructors.
Definition: tls.h:137
void fini()
Definition: tls.h:169
A management class for non-POD thread-local storage.
Definition: tls.h:106
static void thread_fini()
Definition: tls.cpp:118
static void global_fini()
Definition: tls.cpp:85
Static struct to make sure tls_manager&#39;s global init() and fini() are called.
Definition: tls.h:130
static void global_init()
Definition: tls.cpp:77
A namespace for thread-local storage tricks.
Definition: tls.h:83
#define T
Definition: w_okvl_inl.h:45
tls_manager_schwarz()
Constructor: invokes global init of all registered tls initializers.
Definition: tls.h:132