1 /*
2 * Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights
3 * reserved.
4 * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2015-2017 Research Organization for Information Science
6 * and Technology (RIST). All rights reserved.
7 * $COPYRIGHT$
8 *
9 * Additional copyrights may follow
10 *
11 * $HEADER$
12 */
13
14
15 #ifndef OPAL_THREADS_TSD_H
16 #define OPAL_THREADS_TSD_H
17
18 #include "opal_config.h"
19
20 #include <pthread.h>
21
22 #include "opal/constants.h"
23
24 BEGIN_C_DECLS
25
26 /**
27 * @file
28 *
29 * Thread Specific Datastore Interface
30 *
31 * Functions for providing thread-specific datastore capabilities.
32 */
33
34
35 /**
36 * Prototype for callback when tsd data is being destroyed
37 */
38 typedef void (*opal_tsd_destructor_t)(void *value);
39
40 #if defined(DOXYGEN)
41
42 /**
43 * Typedef for thread-specific data key
44 */
45 typedef void* opal_tsd_key_t;
46
47
48 /**
49 * Delete a thread-specific data key
50 *
51 * Delete a thread-specific data key previously returned by
52 * opal_tsd_key_create(). The destructor associated with the key is
53 * not fired in any thread and memory cleanup is the responsibility of
54 * the caller.
55 *
56 * @note Unlike pthread_key_delete, this function should not be called
57 * from within a destructor. It can not be universally supported at
58 * this time.
59 *
60 * @param key[in] The key for accessing thread-specific data
61 *
62 * @retval OPAL_SUCCESS Success
63 * @retval EINVAL Invalid key
64 */
65 OPAL_DECLSPEC int opal_tsd_key_delete(opal_tsd_key_t key);
66
67
68 /**
69 * Set a thread-specific data value
70 *
71 * Associates value with key in the current thread. The value for the
72 * key in other threads is not changed. Different threads may assign
73 * different values to the same key.
74 *
75 * @note This function should not be called within
76 * opal_tsd_key_delete().
77 *
78 * @param key[in] Thread specific data key to modify
79 * @param value[in] Value to associate with key
80 *
81 * @retval OPAL_SUCCESS Success
82 * @retval ENOMEM Insufficient memory exists to associate the
83 * value with the key
84 * @retval EINVAL Invalid key
85 */
86 OPAL_DECLSPEC int opal_tsd_setspecific(opal_tsd_key_t key, void *value);
87
88
89 /**
90 * Get a thread-specific data value
91 *
92 * Get the data associated with the given key, as set by
93 * opal_tsd_setspecific(). If opal_tsd_setspecific() hasn't been
94 * called in the current thread with the given key, NULL is returned
95 * in valuep.
96 *
97 * @param key[in] Thread specific data key to modify
98 * @param value[out] Value to associate with key
99 *
100 * @retval OPAL_SUCCESS Success
101 * @retval ENOMEM Insufficient memory exists to associate the
102 * value with the key
103 * @retval EINVAL Invalid key
104 */
105 OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep);
106
107 #else
108
109 typedef pthread_key_t opal_tsd_key_t;
110
111 static inline int
112 opal_tsd_key_delete(opal_tsd_key_t key)
113 {
114 return pthread_key_delete(key);
115 }
116
117 static inline int
118 opal_tsd_setspecific(opal_tsd_key_t key, void *value)
119 {
120 return pthread_setspecific(key, value);
121 }
122
123 static inline int
124 opal_tsd_getspecific(opal_tsd_key_t key, void **valuep)
125 {
126 *valuep = pthread_getspecific(key);
127 return OPAL_SUCCESS;
128 }
129
130 #endif
131
132 /**
133 * Create thread-specific data key
134 *
135 * Create a thread-specific data key visible to all threads in the
136 * current process. The returned key is valid in all threads,
137 * although the values bound to the key by opal_tsd_setspecific() are
138 * allocated on a per-thread basis and persist for the life of the
139 * calling thread.
140 *
141 * Upon key creation, the value NULL is associated with the new key in
142 * all active threads. When a new thread is created, the value NULL
143 * is associated with all defined keys in the new thread.
144 *
145 * The destructor parameter may be NULL. At thread exit, if
146 * destructor is non-NULL AND the thread has a non-NULL value
147 * associated with the key, the function is called with the current
148 * value as its argument.
149 *
150 * @param key[out] The key for accessing thread-specific data
151 * @param destructor[in] Cleanup function to call when a thread exits
152 *
153 * @retval OPAL_SUCCESS Success
154 * @retval EAGAIN The system lacked the necessary resource to
155 * create another thread specific data key
156 * @retval ENOMEM Insufficient memory exists to create the key
157 */
158 OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key,
159 opal_tsd_destructor_t destructor);
160
161
162 /**
163 * Destruct all thread-specific data keys
164 *
165 * Destruct all thread-specific data keys and invoke the destructor
166 *
167 * This should only be invoked in the main thread.
168 * This is made necessary since destructors are not invoked on the
169 * keys of the main thread, since there is no such thing as
170 * pthread_join(main_thread)
171 *
172 * @retval OPAL_SUCCESS Success
173 */
174 OPAL_DECLSPEC int opal_tsd_keys_destruct(void);
175
176 END_C_DECLS
177
178 #endif /* OPAL_MTHREADS_TSD_H */