| 256 | |
| 257 | |
| 258 | static void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) { |
| 259 | mi_assert_internal(page != NULL); |
| 260 | mi_assert_expensive(mi_page_queue_contains(from, page)); |
| 261 | mi_assert_expensive(!mi_page_queue_contains(to, page)); |
| 262 | |
| 263 | mi_assert_internal((page->xblock_size == to->block_size && page->xblock_size == from->block_size) || |
| 264 | (page->xblock_size == to->block_size && mi_page_queue_is_full(from)) || |
| 265 | (page->xblock_size == from->block_size && mi_page_queue_is_full(to)) || |
| 266 | (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(to)) || |
| 267 | (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_full(to))); |
| 268 | |
| 269 | mi_heap_t* heap = mi_page_heap(page); |
| 270 | if (page->prev != NULL) page->prev->next = page->next; |
| 271 | if (page->next != NULL) page->next->prev = page->prev; |
| 272 | if (page == from->last) from->last = page->prev; |
| 273 | if (page == from->first) { |
| 274 | from->first = page->next; |
| 275 | // update first |
| 276 | mi_assert_internal(mi_heap_contains_queue(heap, from)); |
| 277 | mi_heap_queue_first_update(heap, from); |
| 278 | } |
| 279 | |
| 280 | page->prev = to->last; |
| 281 | page->next = NULL; |
| 282 | if (to->last != NULL) { |
| 283 | mi_assert_internal(heap == mi_page_heap(to->last)); |
| 284 | to->last->next = page; |
| 285 | to->last = page; |
| 286 | } |
| 287 | else { |
| 288 | to->first = page; |
| 289 | to->last = page; |
| 290 | mi_heap_queue_first_update(heap, to); |
| 291 | } |
| 292 | |
| 293 | mi_page_set_in_full(page, mi_page_queue_is_full(to)); |
| 294 | } |
| 295 | |
| 296 | // Only called from `mi_heap_absorb`. |
| 297 | size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append) { |
no test coverage detected