| 1115 | } |
| 1116 | |
| 1117 | static bool |
| 1118 | ctl_init(tsd_t *tsd) { |
| 1119 | bool ret; |
| 1120 | tsdn_t *tsdn = tsd_tsdn(tsd); |
| 1121 | |
| 1122 | malloc_mutex_lock(tsdn, &ctl_mtx); |
| 1123 | if (!ctl_initialized) { |
| 1124 | ctl_arena_t *ctl_sarena, *ctl_darena; |
| 1125 | unsigned i; |
| 1126 | |
| 1127 | /* |
| 1128 | * Allocate demand-zeroed space for pointers to the full |
| 1129 | * range of supported arena indices. |
| 1130 | */ |
| 1131 | if (ctl_arenas == NULL) { |
| 1132 | ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn, |
| 1133 | b0get(), sizeof(ctl_arenas_t), QUANTUM); |
| 1134 | if (ctl_arenas == NULL) { |
| 1135 | ret = true; |
| 1136 | goto label_return; |
| 1137 | } |
| 1138 | } |
| 1139 | |
| 1140 | if (config_stats && ctl_stats == NULL) { |
| 1141 | ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(), |
| 1142 | sizeof(ctl_stats_t), QUANTUM); |
| 1143 | if (ctl_stats == NULL) { |
| 1144 | ret = true; |
| 1145 | goto label_return; |
| 1146 | } |
| 1147 | } |
| 1148 | |
| 1149 | /* |
| 1150 | * Allocate space for the current full range of arenas |
| 1151 | * here rather than doing it lazily elsewhere, in order |
| 1152 | * to limit when OOM-caused errors can occur. |
| 1153 | */ |
| 1154 | if ((ctl_sarena = arenas_i_impl(tsd, MALLCTL_ARENAS_ALL, false, |
| 1155 | true)) == NULL) { |
| 1156 | ret = true; |
| 1157 | goto label_return; |
| 1158 | } |
| 1159 | ctl_sarena->initialized = true; |
| 1160 | |
| 1161 | if ((ctl_darena = arenas_i_impl(tsd, MALLCTL_ARENAS_DESTROYED, |
| 1162 | false, true)) == NULL) { |
| 1163 | ret = true; |
| 1164 | goto label_return; |
| 1165 | } |
| 1166 | ctl_arena_clear(ctl_darena); |
| 1167 | /* |
| 1168 | * Don't toggle ctl_darena to initialized until an arena is |
| 1169 | * actually destroyed, so that arena.<i>.initialized can be used |
| 1170 | * to query whether the stats are relevant. |
| 1171 | */ |
| 1172 | |
| 1173 | ctl_arenas->narenas = narenas_total_get(); |
| 1174 | for (i = 0; i < ctl_arenas->narenas; i++) { |
no test coverage detected