| 205 | static _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE]; |
| 206 | |
| 207 | static mi_thread_data_t* mi_thread_data_alloc(void) { |
| 208 | // try to find thread metadata in the cache |
| 209 | mi_thread_data_t* td; |
| 210 | for (int i = 0; i < TD_CACHE_SIZE; i++) { |
| 211 | td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); |
| 212 | if (td != NULL) { |
| 213 | td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL); |
| 214 | if (td != NULL) { |
| 215 | return td; |
| 216 | } |
| 217 | } |
| 218 | } |
| 219 | // if that fails, allocate directly from the OS |
| 220 | td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); |
| 221 | if (td == NULL) { |
| 222 | // if this fails, try once more. (issue #257) |
| 223 | td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); |
| 224 | if (td == NULL) { |
| 225 | // really out of memory |
| 226 | _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t)); |
| 227 | } |
| 228 | } |
| 229 | return td; |
| 230 | } |
| 231 | |
| 232 | static void mi_thread_data_free( mi_thread_data_t* tdfree ) { |
| 233 | // try to add the thread metadata to the cache |
no test coverage detected