| 267 | } |
| 268 | |
| 269 | tsd_t * |
| 270 | tsd_fetch_slow(tsd_t *tsd, bool minimal) { |
| 271 | assert(!tsd_fast(tsd)); |
| 272 | |
| 273 | if (tsd_state_get(tsd) == tsd_state_nominal_slow) { |
| 274 | /* |
| 275 | * On slow path but no work needed. Note that we can't |
| 276 | * necessarily *assert* that we're slow, because we might be |
| 277 | * slow because of an asynchronous modification to global state, |
| 278 | * which might be asynchronously modified *back*. |
| 279 | */ |
| 280 | } else if (tsd_state_get(tsd) == tsd_state_nominal_recompute) { |
| 281 | tsd_slow_update(tsd); |
| 282 | } else if (tsd_state_get(tsd) == tsd_state_uninitialized) { |
| 283 | if (!minimal) { |
| 284 | if (tsd_booted) { |
| 285 | tsd_state_set(tsd, tsd_state_nominal); |
| 286 | tsd_slow_update(tsd); |
| 287 | /* Trigger cleanup handler registration. */ |
| 288 | tsd_set(tsd); |
| 289 | tsd_data_init(tsd); |
| 290 | } |
| 291 | } else { |
| 292 | tsd_state_set(tsd, tsd_state_minimal_initialized); |
| 293 | tsd_set(tsd); |
| 294 | tsd_data_init_nocleanup(tsd); |
| 295 | } |
| 296 | } else if (tsd_state_get(tsd) == tsd_state_minimal_initialized) { |
| 297 | if (!minimal) { |
| 298 | /* Switch to fully initialized. */ |
| 299 | tsd_state_set(tsd, tsd_state_nominal); |
| 300 | assert(*tsd_reentrancy_levelp_get(tsd) >= 1); |
| 301 | (*tsd_reentrancy_levelp_get(tsd))--; |
| 302 | tsd_slow_update(tsd); |
| 303 | tsd_data_init(tsd); |
| 304 | } else { |
| 305 | assert_tsd_data_cleanup_done(tsd); |
| 306 | } |
| 307 | } else if (tsd_state_get(tsd) == tsd_state_purgatory) { |
| 308 | tsd_state_set(tsd, tsd_state_reincarnated); |
| 309 | tsd_set(tsd); |
| 310 | tsd_data_init_nocleanup(tsd); |
| 311 | } else { |
| 312 | assert(tsd_state_get(tsd) == tsd_state_reincarnated); |
| 313 | } |
| 314 | |
| 315 | return tsd; |
| 316 | } |
| 317 | |
| 318 | void * |
| 319 | malloc_tsd_malloc(size_t size) { |
no test coverage detected