| 153 | ----------------------------------------------------------- */ |
| 154 | |
| 155 | static mi_decl_noinline void* mi_arena_alloc_from(mi_arena_t* arena, size_t arena_index, size_t needed_bcount, |
| 156 | bool* commit, bool* large, bool* is_pinned, bool* is_zero, |
| 157 | mi_arena_id_t req_arena_id, size_t* memid, mi_os_tld_t* tld) |
| 158 | { |
| 159 | MI_UNUSED(arena_index); |
| 160 | mi_assert_internal(mi_arena_id_index(arena->id) == arena_index); |
| 161 | if (!mi_arena_id_is_suitable(arena->id, arena->exclusive, req_arena_id)) return NULL; |
| 162 | |
| 163 | mi_bitmap_index_t bitmap_index; |
| 164 | if (!mi_arena_alloc(arena, needed_bcount, &bitmap_index)) return NULL; |
| 165 | |
| 166 | // claimed it! set the dirty bits (todo: no need for an atomic op here?) |
| 167 | void* p = arena->start + (mi_bitmap_index_bit(bitmap_index)*MI_ARENA_BLOCK_SIZE); |
| 168 | *memid = mi_arena_memid_create(arena->id, arena->exclusive, bitmap_index); |
| 169 | *is_zero = _mi_bitmap_claim_across(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL); |
| 170 | *large = arena->is_large; |
| 171 | *is_pinned = (arena->is_large || !arena->allow_decommit); |
| 172 | if (arena->blocks_committed == NULL) { |
| 173 | // always committed |
| 174 | *commit = true; |
| 175 | } |
| 176 | else if (*commit) { |
| 177 | // arena not committed as a whole, but commit requested: ensure commit now |
| 178 | bool any_uncommitted; |
| 179 | _mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted); |
| 180 | if (any_uncommitted) { |
| 181 | bool commit_zero; |
| 182 | _mi_os_commit(p, needed_bcount * MI_ARENA_BLOCK_SIZE, &commit_zero, tld->stats); |
| 183 | if (commit_zero) *is_zero = true; |
| 184 | } |
| 185 | } |
| 186 | else { |
| 187 | // no need to commit, but check if already fully committed |
| 188 | *commit = _mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index); |
| 189 | } |
| 190 | return p; |
| 191 | } |
| 192 | |
| 193 | // allocate from an arena with fallback to the OS |
| 194 | static mi_decl_noinline void* mi_arena_allocate(int numa_node, size_t size, size_t alignment, bool* commit, bool* large, |
no test coverage detected