| 1167 | } |
| 1168 | |
| 1169 | void |
| 1170 | arena_destroy(tsd_t *tsd, arena_t *arena) { |
| 1171 | assert(base_ind_get(arena->base) >= narenas_auto); |
| 1172 | assert(arena_nthreads_get(arena, false) == 0); |
| 1173 | assert(arena_nthreads_get(arena, true) == 0); |
| 1174 | |
| 1175 | /* |
| 1176 | * No allocations have occurred since arena_reset() was called. |
| 1177 | * Furthermore, the caller (arena_i_destroy_ctl()) purged all cached |
| 1178 | * extents, so only retained extents may remain. |
| 1179 | */ |
| 1180 | assert(extents_npages_get(&arena->extents_dirty) == 0); |
| 1181 | assert(extents_npages_get(&arena->extents_muzzy) == 0); |
| 1182 | |
| 1183 | /* Deallocate retained memory. */ |
| 1184 | arena_destroy_retained(tsd_tsdn(tsd), arena); |
| 1185 | |
| 1186 | /* |
| 1187 | * Remove the arena pointer from the arenas array. We rely on the fact |
| 1188 | * that there is no way for the application to get a dirty read from the |
| 1189 | * arenas array unless there is an inherent race in the application |
| 1190 | * involving access of an arena being concurrently destroyed. The |
| 1191 | * application must synchronize knowledge of the arena's validity, so as |
| 1192 | * long as we use an atomic write to update the arenas array, the |
| 1193 | * application will get a clean read any time after it synchronizes |
| 1194 | * knowledge that the arena is no longer valid. |
| 1195 | */ |
| 1196 | arena_set(base_ind_get(arena->base), NULL); |
| 1197 | |
| 1198 | /* |
| 1199 | * Destroy the base allocator, which manages all metadata ever mapped by |
| 1200 | * this arena. |
| 1201 | */ |
| 1202 | base_delete(tsd_tsdn(tsd), arena->base); |
| 1203 | } |
| 1204 | |
| 1205 | static extent_t * |
| 1206 | arena_slab_alloc_hard(tsdn_t *tsdn, arena_t *arena, |
no test coverage detected