| 52 | } |
| 53 | |
| 54 | static void |
| 55 | base_unmap(tsdn_t *tsdn, extent_hooks_t *extent_hooks, unsigned ind, void *addr, |
| 56 | size_t size) { |
| 57 | /* |
| 58 | * Cascade through dalloc, decommit, purge_forced, and purge_lazy, |
| 59 | * stopping at first success. This cascade is performed for consistency |
| 60 | * with the cascade in extent_dalloc_wrapper() because an application's |
| 61 | * custom hooks may not support e.g. dalloc. This function is only ever |
| 62 | * called as a side effect of arena destruction, so although it might |
| 63 | * seem pointless to do anything besides dalloc here, the application |
| 64 | * may in fact want the end state of all associated virtual memory to be |
| 65 | * in some consistent-but-allocated state. |
| 66 | */ |
| 67 | if (extent_hooks == &extent_hooks_default) { |
| 68 | if (!extent_dalloc_mmap(addr, size)) { |
| 69 | goto label_done; |
| 70 | } |
| 71 | if (!pages_decommit(addr, size)) { |
| 72 | goto label_done; |
| 73 | } |
| 74 | if (!pages_purge_forced(addr, size)) { |
| 75 | goto label_done; |
| 76 | } |
| 77 | if (!pages_purge_lazy(addr, size)) { |
| 78 | goto label_done; |
| 79 | } |
| 80 | /* Nothing worked. This should never happen. */ |
| 81 | not_reached(); |
| 82 | } else { |
| 83 | tsd_t *tsd = tsdn_null(tsdn) ? tsd_fetch() : tsdn_tsd(tsdn); |
| 84 | pre_reentrancy(tsd, NULL); |
| 85 | if (extent_hooks->dalloc != NULL && |
| 86 | !extent_hooks->dalloc(extent_hooks, addr, size, true, |
| 87 | ind)) { |
| 88 | goto label_post_reentrancy; |
| 89 | } |
| 90 | if (extent_hooks->decommit != NULL && |
| 91 | !extent_hooks->decommit(extent_hooks, addr, size, 0, size, |
| 92 | ind)) { |
| 93 | goto label_post_reentrancy; |
| 94 | } |
| 95 | if (extent_hooks->purge_forced != NULL && |
| 96 | !extent_hooks->purge_forced(extent_hooks, addr, size, 0, |
| 97 | size, ind)) { |
| 98 | goto label_post_reentrancy; |
| 99 | } |
| 100 | if (extent_hooks->purge_lazy != NULL && |
| 101 | !extent_hooks->purge_lazy(extent_hooks, addr, size, 0, size, |
| 102 | ind)) { |
| 103 | goto label_post_reentrancy; |
| 104 | } |
| 105 | /* Nothing worked. That's the application's problem. */ |
| 106 | label_post_reentrancy: |
| 107 | post_reentrancy(tsd); |
| 108 | } |
| 109 | label_done: |
| 110 | if (metadata_thp_madvise()) { |
| 111 | /* Set NOHUGEPAGE after unmap to avoid kernel defrag. */ |
no test coverage detected