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 */