OpenMPI  0.1.1
tsd.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Los Alamos National Security, LLC. All rights
3  * reserved.
4  * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
5  * $COPYRIGHT$
6  *
7  * Additional copyrights may follow
8  *
9  * $HEADER$
10  */
11 
12 
13 #ifndef OPAL_THREADS_TSD_H
14 #define OPAL_THREADS_TSD_H
15 
16 #include "opal_config.h"
17 
18 #if OPAL_HAVE_POSIX_THREADS
19 #include <pthread.h>
20 #elif OPAL_HAVE_SOLARIS_THREADS
21 #include <thread.h>
22 #endif
23 
24 #include "opal/constants.h"
25 
26 BEGIN_C_DECLS
27 
28 /**
29  * @file
30  *
31  * Thread Specific Datastore Interface
32  *
33  * Functions for providing thread-specific datastore capabilities.
34  */
35 
36 
37 /**
38  * Prototype for callback when tsd data is being destroyed
39  */
40 typedef void (*opal_tsd_destructor_t)(void *value);
41 
42 #if defined(DOXYGEN)
43 
44 /**
45  * Typedef for thread-specific data key
46  */
47 typedef void* opal_tsd_key_t;
48 
49 
50 /**
51  * Create thread-specific data key
52  *
53  * Create a thread-specific data key visible to all threads in the
54  * current process. The returned key is valid in all threads,
55  * although the values bound to the key by opal_tsd_setspecific() are
56  * allocated on a per-thread basis and persist for the life of the
57  * calling thread.
58  *
59  * Upon key creation, the value NULL is associated with the new key in
60  * all active threads. When a new thread is created, the value NULL
61  * is associated with all defined keys in the new thread.
62  *
63  * The destructor parameter may be NULL. At thread exit, if
64  * destructor is non-NULL AND the thread has a non-NULL value
65  * associated with the key, the function is called with the current
66  * value as its argument.
67  *
68  * @param key[out] The key for accessing thread-specific data
69  * @param destructor[in] Cleanup function to call when a thread exits
70  *
71  * @retval OPAL_SUCCESS Success
72  * @retval EAGAIN The system lacked the necessary resource to
73  * create another thread specific data key
74  * @retval ENOMEM Insufficient memory exists to create the key
75  */
76 OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key,
77  opal_tsd_destructor_t destructor);
78 
79 
80 /**
81  * Delete a thread-specific data key
82  *
83  * Delete a thread-specific data key previously returned by
84  * opal_tsd_key_create(). The destructor associated with the key is
85  * not fired in any thread and memory cleanup is the responsibility of
86  * the caller.
87  *
88  * @note Unlike pthread_key_delete, this function should not be called
89  * from within a destructor. It can not be universally supported at
90  * this time.
91  *
92  * @param key[in] The key for accessing thread-specific data
93  *
94  * @retval OPAL_SUCCESS Success
95  * @retval EINVAL Invalid key
96  */
97 OPAL_DECLSPEC int opal_tsd_key_delete(opal_tsd_key_t key);
98 
99 
100 /**
101  * Set a thread-specific data value
102  *
103  * Associates value with key in the current thread. The value for the
104  * key in other threads is not changed. Different threads may assign
105  * different values to the same key.
106  *
107  * @note This function should not be called within
108  * opal_tsd_key_delete().
109  *
110  * @param key[in] Thread specific data key to modify
111  * @param value[in] Value to associate with key
112  *
113  * @retval OPAL_SUCCESS Success
114  * @retval ENOMEM Insufficient memory exists to associate the
115  * value with the key
116  * @retval EINVAL Invalid key
117  */
118 OPAL_DECLSPEC int opal_tsd_setspecific(opal_tsd_key_t key, void *value);
119 
120 
121 /**
122  * Get a thread-specific data value
123  *
124  * Get the data associated with the given key, as set by
125  * opal_tsd_setspecific(). If opal_tsd_setspecific() hasn't been
126  * called in the current thread with the given key, NULL is returned
127  * in valuep.
128  *
129  * @param key[in] Thread specific data key to modify
130  * @param value[out] Value to associate with key
131  *
132  * @retval OPAL_SUCCESS Success
133  * @retval ENOMEM Insufficient memory exists to associate the
134  * value with the key
135  * @retval EINVAL Invalid key
136  */
137 OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep);
138 
139 #elif OPAL_HAVE_POSIX_THREADS
140 
141 typedef pthread_key_t opal_tsd_key_t;
142 
143 static inline int
145  opal_tsd_destructor_t destructor)
146 {
147  return pthread_key_create(key, destructor);
148 }
149 
150 static inline int
152 {
153  return pthread_key_delete(key);
154 }
155 
156 static inline int
157 opal_tsd_setspecific(opal_tsd_key_t key, void *value)
158 {
159  return pthread_setspecific(key, value);
160 }
161 
162 static inline int
163 opal_tsd_getspecific(opal_tsd_key_t key, void **valuep)
164 {
165  *valuep = pthread_getspecific(key);
166  return OPAL_SUCCESS;
167 }
168 
169 #elif OPAL_HAVE_SOLARIS_THREADS
170 
171 typedef thread_key_t opal_tsd_key_t;
172 
173 static inline int
175  opal_tsd_destructor_t destructor)
176 {
177  return thr_keycreate(key, destructor);
178 }
179 
180 static inline int
182 {
183  return OPAL_SUCCESS;
184 }
185 
186 static inline int
187 opal_tsd_setspecific(opal_tsd_key_t key, void *value)
188 {
189  return thr_setspecific(key, value);
190 }
191 
192 static inline int
193 opal_tsd_getspecific(opal_tsd_key_t key, void **valuep)
194 {
195  return thr_getspecific(key, valuep);
196 }
197 
198 #elif defined(__WINDOWS__)
199 
200 /* BWB - FIX ME - this is still not quite right -- we also need to
201  implement support for running the destructors when a thread exits,
202  but I'm not sure we have a framework for doing that just yet. */
203 
204 typedef DWORD opal_tsd_key_t;
205 
206 static inline int
208  opal_tsd_destructor_t destructor)
209 {
210  *key = TlsAlloc();
211 
212  return (*key == TLS_OUT_OF_INDEXES) ? OPAL_ERROR : OPAL_SUCCESS;
213 }
214 
215 static inline int
217 {
218  key = TlsFree(key);
219 
220  return (key == 0) ? OPAL_ERROR : OPAL_SUCCESS;
221 }
222 
223 static inline int
224 opal_tsd_setspecific(opal_tsd_key_t key, void *value)
225 {
226  BOOL ret = TlsSetValue(key, (LPVOID) value);
227 
228  return (ret) ? OPAL_SUCCESS : OPAL_ERROR;
229 }
230 
231 static inline int
232 opal_tsd_getspecific(opal_tsd_key_t key, void **valuep)
233 {
234  *valuep = TlsGetValue(key);
235  return OPAL_SUCCESS;
236 }
237 
238 #else
239 
240 typedef int opal_tsd_key_t;
241 
242 OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key,
243  opal_tsd_destructor_t destructor);
244 
245 OPAL_DECLSPEC int opal_tsd_key_delete(opal_tsd_key_t key);
246 
247 OPAL_DECLSPEC int opal_tsd_setspecific(opal_tsd_key_t key, void *value);
248 
249 OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep);
250 
251 #endif
252 
253 END_C_DECLS
254 
255 #endif /* OPAL_MTHREADS_TSD_H */
Functions for multi-threaded applications using Libevent.
OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor)
Create thread-specific data key.
Definition: tsd.c:60
OPAL_DECLSPEC int opal_tsd_setspecific(opal_tsd_key_t key, void *value)
Set a thread-specific data value.
Definition: tsd.c:101
void(* opal_tsd_destructor_t)(void *value)
Prototype for callback when tsd data is being destroyed.
Definition: tsd.h:40
OPAL_DECLSPEC int opal_tsd_key_delete(opal_tsd_key_t key)
Delete a thread-specific data key.
Definition: tsd.c:88
void * opal_tsd_key_t
Typedef for thread-specific data key.
Definition: tsd.h:47
OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep)
Get a thread-specific data value.
Definition: tsd.c:110