| 1433 | |
| 1434 | |
| 1435 | void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld) |
| 1436 | { |
| 1437 | mi_segment_t* segment; |
| 1438 | int max_tries = (force ? 16*1024 : 1024); // limit latency |
| 1439 | if (force) { |
| 1440 | mi_abandoned_visited_revisit(); |
| 1441 | } |
| 1442 | while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { |
| 1443 | mi_segment_check_free(segment,0,0,tld); // try to free up pages (due to concurrent frees) |
| 1444 | if (segment->used == 0) { |
| 1445 | // free the segment (by forced reclaim) to make it available to other threads. |
| 1446 | // note: we could in principle optimize this by skipping reclaim and directly |
| 1447 | // freeing but that would violate some invariants temporarily) |
| 1448 | mi_segment_reclaim(segment, heap, 0, NULL, tld); |
| 1449 | } |
| 1450 | else { |
| 1451 | // otherwise, decommit if needed and push on the visited list |
| 1452 | // note: forced decommit can be expensive if many threads are destroyed/created as in mstress. |
| 1453 | mi_segment_delayed_decommit(segment, force, tld->stats); |
| 1454 | mi_abandoned_visited_push(segment); |
| 1455 | } |
| 1456 | } |
| 1457 | } |
| 1458 | |
| 1459 | /* ----------------------------------------------------------- |
| 1460 | Reclaim or allocate |
no test coverage detected