logalloc: introduce prime_segment_pool()

To segregate std and lsa allocations, we prime the segment pool
during initialization so that lsa will release lower-addressed
memory to std, rather than lsa and std competing for memory at
random addresses.

However, tests often evict all of lsa memory for their own
purposes, which defeats this priming.

Extract the functionality into a new prime_segment_pool()
function for use in tests that rely on allocation segregation.
This commit is contained in:
Avi Kivity
2018-04-02 15:22:32 +03:00
parent ff6325ee7e
commit 2baa16b371
2 changed files with 14 additions and 0 deletions

View File

@@ -426,6 +426,7 @@ private:
}
public:
segment_pool();
void prime();
segment* new_segment(region::impl* r);
segment_descriptor& descriptor(const segment*);
// Returns segment containing given object or nullptr.
@@ -658,6 +659,10 @@ segment_pool::segment_pool()
, _lsa_owned_segments_bitmap(max_segments())
, _lsa_free_segments_bitmap(max_segments())
{
prime();
}
void segment_pool::prime() {
auto old_emergency_reserve = std::exchange(_emergency_reserve_max, std::numeric_limits<size_t>::max());
try {
// Allocate all of memory so that we occupy the top part. Afterwards, we'll start
@@ -688,6 +693,7 @@ class segment_pool {
size_t _segments_in_use{};
size_t _non_lsa_memory_in_use = 0;
public:
void prime() {}
segment* new_segment(region::impl* r) {
if (_free_segments.empty()) {
std::unique_ptr<segment, free_deleter> seg{new (with_alignment(segment::size)) segment};
@@ -2114,6 +2120,10 @@ void region_group::on_request_expiry::operator()(std::unique_ptr<allocating_func
func->fail(std::make_exception_ptr(timed_out_error()));
}
void prime_segment_pool() {
shard_segment_pool.prime();
}
}
// Orders segments by free space, assuming all segments have the same size.

View File

@@ -730,4 +730,8 @@ public:
}
};
// for tests, make sure a new test is started with a primed segment pool (all segments
// allocated so segregated allocation can work)
void prime_segment_pool();
}