* @brief Destroy and clean up a thread data structure along with associated resources * * This function releases all resources associated with a thread data structure including: * - Thread-local storage (TLS) destructors execution * - Joinable semaphore deletion * - Global thread table entry cleanup * - Memory deallocation after proper resource release * * @param ptd Pointer to the thread
| 203 | * - Thread-safe operation through spinlock protection during critical sections |
| 204 | */ |
| 205 | void _pthread_data_destroy(_pthread_data_t *ptd) |
| 206 | { |
| 207 | pthread_t pth; |
| 208 | |
| 209 | if (ptd) |
| 210 | { |
| 211 | /* if this thread create the local thread data, |
| 212 | * destruct thread local key |
| 213 | */ |
| 214 | if (ptd->tls != RT_NULL) |
| 215 | { |
| 216 | int index; |
| 217 | #ifdef RT_USING_CPLUSPLUS11 |
| 218 | /* If C++11 is enabled and emutls is used, |
| 219 | * destructors of C++ object must be called safely. |
| 220 | */ |
| 221 | extern pthread_key_t emutls_get_pthread_key(void); |
| 222 | pthread_key_t emutls_pthread_key = emutls_get_pthread_key(); |
| 223 | |
| 224 | if (emutls_pthread_key != NOT_USE_CXX_TLS) |
| 225 | { |
| 226 | /* If execution reaches here, C++ 'thread_local' may be used. |
| 227 | * Destructors of c++ class object must be called before emutls_key_destructor. |
| 228 | */ |
| 229 | int start = ((emutls_pthread_key - 1 + PTHREAD_KEY_MAX) % PTHREAD_KEY_MAX); |
| 230 | int i = 0; |
| 231 | for (index = start; i < PTHREAD_KEY_MAX; index = (index - 1 + PTHREAD_KEY_MAX) % PTHREAD_KEY_MAX, i ++) |
| 232 | { |
| 233 | _destroy_item(index, ptd); |
| 234 | } |
| 235 | } |
| 236 | else |
| 237 | #endif |
| 238 | { |
| 239 | /* If only C TLS is used, that is, POSIX TLS or __Thread_local, |
| 240 | * just iterate the _thread_keys from index 0. |
| 241 | */ |
| 242 | for (index = 0; index < PTHREAD_KEY_MAX; index ++) |
| 243 | { |
| 244 | _destroy_item(index, ptd); |
| 245 | } |
| 246 | } |
| 247 | /* release tls area */ |
| 248 | rt_free(ptd->tls); |
| 249 | ptd->tls = RT_NULL; |
| 250 | } |
| 251 | |
| 252 | pth = _pthread_data_get_pth(ptd); |
| 253 | /* remove from pthread table */ |
| 254 | rt_hw_spin_lock(&pth_lock); |
| 255 | pth_table[pth] = NULL; |
| 256 | rt_hw_spin_unlock(&pth_lock); |
| 257 | |
| 258 | /* delete joinable semaphore */ |
| 259 | if (ptd->joinable_sem != RT_NULL) |
| 260 | { |
| 261 | rt_sem_delete(ptd->joinable_sem); |
| 262 | ptd->joinable_sem = RT_NULL; |
no test coverage detected