Skip to content

Commit 872d553

Browse files
committed
Fixed Windows and Mac builds
1 parent e025ac5 commit 872d553

File tree

2 files changed

+73
-17
lines changed

2 files changed

+73
-17
lines changed

core/resource_manager.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ struct IResearchMemoryManager : public IResourceManager {
8888
IRS_ASSERT(this != &kForbidden);
8989
IRS_ASSERT(value >= 0);
9090

91-
if (0 == _memoryLimit) {
91+
if (_memoryLimit == 0) {
9292
// since we have no limit, we can simply use fetch-add for the increment
9393
_current.fetch_add(value, std::memory_order_relaxed);
9494
} else {
9595
// we only want to perform the update if we don't exceed the limit!
96-
std::uint64_t cur = _current.load(std::memory_order_relaxed);
97-
std::uint64_t next;
96+
size_t cur = _current.load(std::memory_order_relaxed);
97+
size_t next;
9898
do {
9999
next = cur + value;
100100
if (IRS_UNLIKELY(next > _memoryLimit.load(std::memory_order_relaxed))) {
@@ -117,6 +117,10 @@ struct IResearchMemoryManager : public IResourceManager {
117117
_memoryLimit.store(memoryLimit);
118118
}
119119

120+
size_t getCurrentUsage() {
121+
return _current.load(std::memory_order_relaxed);
122+
}
123+
120124
private:
121125
// This limit should be set exclusively by IResearchFeature.
122126
// During IResearchFeature::validateOptions() this limit is set to a

tests/memory/IResearchMemoryManager_tests.cpp

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,61 @@ struct LargeData {
3333
char data[1024];
3434
};
3535

36-
TEST(IResearchMemoryLimitTest, no_limit_set_allows_infinite_allocations) {
36+
class IResearchMemoryLimitTest : public ::testing::Test {
37+
38+
// IResearchMemoryManager's state persists between tests
39+
// since it's a static singleton instance. We must clear
40+
// the used memory at the end of each test so that the next
41+
// test gets a fresh start.
42+
void clearUsedMemory() {
43+
44+
auto memoryMgr = IResearchMemoryManager::GetInstance();
45+
memoryMgr->Decrease(memoryMgr->getCurrentUsage());
46+
}
47+
48+
virtual void TearDown() override {
49+
clearUsedMemory();
50+
}
51+
};
52+
53+
TEST_F(IResearchMemoryLimitTest, memory_manager_smoke_test) {
54+
auto memoryMgr = IResearchMemoryManager::GetInstance();
55+
56+
auto elemSize = sizeof(uint64_t);
57+
auto maxElems = 2;
58+
memoryMgr->SetMemoryLimit(maxElems * elemSize);
59+
60+
// Add 10 elems.
61+
for (int i = 0; i < maxElems; i++) {
62+
ASSERT_NO_THROW(memoryMgr->Increase(elemSize));
63+
}
64+
65+
// Try adding 11th element. Should throw.
66+
ASSERT_THROW(memoryMgr->Increase(elemSize), std::bad_alloc);
67+
68+
// Remove 1 element and try again, shouldn't throw.
69+
memoryMgr->Decrease(elemSize);
70+
ASSERT_NO_THROW(memoryMgr->Increase(elemSize));
71+
72+
// Limit reached. Should start throwing again.
73+
ASSERT_THROW(memoryMgr->Increase(elemSize), std::bad_alloc);
74+
75+
// Increase the limit and add 1 more element, shouldn't throw.
76+
memoryMgr->SetMemoryLimit((maxElems + 1) * elemSize);
77+
ASSERT_NO_THROW(memoryMgr->Increase(elemSize));
78+
79+
// Adding any more elements should throw again
80+
ASSERT_THROW(memoryMgr->Increase(elemSize), std::bad_alloc);
81+
}
82+
83+
TEST_F(IResearchMemoryLimitTest, no_limit_set_allows_infinite_allocations) {
3784

3885
// The expectation is to allow potentially infinite allocations
3986
// even if we're testing with just 1MB.
4087

88+
auto memoryMgr = IResearchMemoryManager::GetInstance();
89+
memoryMgr->SetMemoryLimit(0);
90+
4191
// allocate vector
4292
ManagedVector<LargeData> vec;
4393

@@ -46,7 +96,7 @@ TEST(IResearchMemoryLimitTest, no_limit_set_allows_infinite_allocations) {
4696
}
4797
}
4898

49-
TEST(IResearchMemoryLimitTest, zero_limit_allow_infinite_allocations) {
99+
TEST_F(IResearchMemoryLimitTest, zero_limit_allow_infinite_allocations) {
50100

51101
auto memoryMgr = IResearchMemoryManager::GetInstance();
52102
memoryMgr->SetMemoryLimit(0);
@@ -59,7 +109,7 @@ TEST(IResearchMemoryLimitTest, zero_limit_allow_infinite_allocations) {
59109
}
60110
}
61111

62-
TEST(IResearchMemoryLimitTest, managed_allocator_smoke_test) {
112+
TEST_F(IResearchMemoryLimitTest, managed_allocator_smoke_test) {
63113

64114
auto memoryMgr = IResearchMemoryManager::GetInstance();
65115
memoryMgr->SetMemoryLimit(3);
@@ -72,21 +122,23 @@ TEST(IResearchMemoryLimitTest, managed_allocator_smoke_test) {
72122
ASSERT_THROW(arr.push_back('c'), std::bad_alloc);
73123
}
74124

75-
TEST(IResearchMemoryLimitTest, memory_manager_smoke_test) {
125+
TEST_F(IResearchMemoryLimitTest, memory_manager_managed_vector_test) {
76126

77127
// set limit
128+
size_t maxElements { 4 };
78129
auto memoryMgr = IResearchMemoryManager::GetInstance();
79-
memoryMgr->SetMemoryLimit(47);
80-
81-
// allocate vector
82-
ManagedVector<uint64_t> vec;
83-
vec.push_back(10); // Allocate 8 bytes
84-
vec.push_back(11); // Allocate 16, Free previous 8, Copy both elements in the new array.
130+
memoryMgr->SetMemoryLimit(maxElements * sizeof(uint64_t));
85131

86-
ASSERT_THROW(vec.push_back(12), std::bad_alloc); // Allocate 32 while holding previous 16, total 48 (bad_alloc)
132+
auto addElemsToVec = [](size_t count) {
133+
ManagedVector<uint64_t> vec;
134+
for (size_t i = 0; i < count; i++) {
135+
vec.push_back(i);
136+
}
137+
};
87138

88-
// Increase memory limit to accommodate the 3rd element.
89-
memoryMgr->SetMemoryLimit(48);
139+
ASSERT_THROW(addElemsToVec(maxElements + 1), std::bad_alloc);
90140

91-
ASSERT_NO_THROW(vec.push_back(12));
141+
// Increase memory limit.
142+
memoryMgr->SetMemoryLimit(maxElements * 3 * sizeof(uint64_t));
143+
ASSERT_NO_THROW(addElemsToVec(maxElements + 1));
92144
}

0 commit comments

Comments
 (0)