Map an aligned set of spans, taking configured mapping granularity and the page size into account
| 1181 | |
| 1182 | //! Map an aligned set of spans, taking configured mapping granularity and the page size into account |
| 1183 | static span_t* |
| 1184 | _rpmalloc_span_map_aligned_count(heap_t* heap, size_t span_count) { |
| 1185 | //If we already have some, but not enough, reserved spans, release those to heap cache and map a new |
| 1186 | //full set of spans. Otherwise we would waste memory if page size > span size (huge pages) |
| 1187 | size_t aligned_span_count = _rpmalloc_span_align_count(span_count); |
| 1188 | size_t align_offset = 0; |
| 1189 | span_t* span = (span_t*)_rpmalloc_mmap(aligned_span_count * _memory_span_size, &align_offset); |
| 1190 | if (!span) |
| 1191 | return 0; |
| 1192 | _rpmalloc_span_initialize(span, aligned_span_count, span_count, align_offset); |
| 1193 | _rpmalloc_stat_inc(&_master_spans); |
| 1194 | if (span_count <= LARGE_CLASS_COUNT) |
| 1195 | _rpmalloc_stat_inc(&heap->span_use[span_count - 1].spans_map_calls); |
| 1196 | if (aligned_span_count > span_count) { |
| 1197 | span_t* reserved_spans = (span_t*)pointer_offset(span, span_count * _memory_span_size); |
| 1198 | size_t reserved_count = aligned_span_count - span_count; |
| 1199 | if (heap->spans_reserved) { |
| 1200 | _rpmalloc_span_mark_as_subspan_unless_master(heap->span_reserve_master, heap->span_reserve, heap->spans_reserved); |
| 1201 | _rpmalloc_heap_cache_insert(heap, heap->span_reserve); |
| 1202 | } |
| 1203 | if (reserved_count > _memory_heap_reserve_count) { |
| 1204 | // If huge pages or eager spam map count, the global reserve spin lock is held by caller, _rpmalloc_span_map |
| 1205 | rpmalloc_assert(atomic_load32(&_memory_global_lock) == 1, "Global spin lock not held as expected"); |
| 1206 | size_t remain_count = reserved_count - _memory_heap_reserve_count; |
| 1207 | reserved_count = _memory_heap_reserve_count; |
| 1208 | span_t* remain_span = (span_t*)pointer_offset(reserved_spans, reserved_count * _memory_span_size); |
| 1209 | if (_memory_global_reserve) { |
| 1210 | _rpmalloc_span_mark_as_subspan_unless_master(_memory_global_reserve_master, _memory_global_reserve, _memory_global_reserve_count); |
| 1211 | _rpmalloc_span_unmap(_memory_global_reserve); |
| 1212 | } |
| 1213 | _rpmalloc_global_set_reserved_spans(span, remain_span, remain_count); |
| 1214 | } |
| 1215 | _rpmalloc_heap_set_reserved_spans(heap, span, reserved_spans, reserved_count); |
| 1216 | } |
| 1217 | return span; |
| 1218 | } |
| 1219 | |
| 1220 | //! Map in memory pages for the given number of spans (or use previously reserved pages) |
| 1221 | static span_t* |
no test coverage detected