| 461 | |
| 462 | |
| 463 | static bool mi_segment_commitx(mi_segment_t* segment, bool commit, uint8_t* p, size_t size, mi_stats_t* stats) { |
| 464 | mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask)); |
| 465 | |
| 466 | // commit liberal, but decommit conservative |
| 467 | uint8_t* start = NULL; |
| 468 | size_t full_size = 0; |
| 469 | mi_commit_mask_t mask; |
| 470 | mi_segment_commit_mask(segment, !commit/*conservative*/, p, size, &start, &full_size, &mask); |
| 471 | if (mi_commit_mask_is_empty(&mask) || full_size==0) return true; |
| 472 | |
| 473 | if (commit && !mi_commit_mask_all_set(&segment->commit_mask, &mask)) { |
| 474 | bool is_zero = false; |
| 475 | mi_commit_mask_t cmask; |
| 476 | mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); |
| 477 | _mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap |
| 478 | if (!_mi_os_commit(start,full_size,&is_zero,stats)) return false; |
| 479 | mi_commit_mask_set(&segment->commit_mask, &mask); |
| 480 | } |
| 481 | else if (!commit && mi_commit_mask_any_set(&segment->commit_mask, &mask)) { |
| 482 | mi_assert_internal((void*)start != (void*)segment); |
| 483 | //mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &mask)); |
| 484 | |
| 485 | mi_commit_mask_t cmask; |
| 486 | mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); |
| 487 | _mi_stat_increase(&_mi_stats_main.committed, full_size - _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap |
| 488 | if (segment->allow_decommit) { |
| 489 | _mi_os_decommit(start, full_size, stats); // ok if this fails |
| 490 | } |
| 491 | mi_commit_mask_clear(&segment->commit_mask, &mask); |
| 492 | } |
| 493 | // increase expiration of reusing part of the delayed decommit |
| 494 | if (commit && mi_commit_mask_any_set(&segment->decommit_mask, &mask)) { |
| 495 | segment->decommit_expire = _mi_clock_now() + mi_option_get(mi_option_decommit_delay); |
| 496 | } |
| 497 | // always undo delayed decommits |
| 498 | mi_commit_mask_clear(&segment->decommit_mask, &mask); |
| 499 | return true; |
| 500 | } |
| 501 | |
| 502 | static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { |
| 503 | mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask)); |
no test coverage detected