]>
Commit | Line | Data |
---|---|---|
1d09f67e TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership. The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | #include <algorithm> | |
19 | #include <cstdint> | |
20 | ||
21 | #include <gtest/gtest.h> | |
22 | ||
23 | #include "arrow/memory_pool.h" | |
24 | #include "arrow/memory_pool_test.h" | |
25 | #include "arrow/status.h" | |
26 | #include "arrow/testing/gtest_util.h" | |
27 | ||
28 | namespace arrow { | |
29 | ||
30 | struct DefaultMemoryPoolFactory { | |
31 | static MemoryPool* memory_pool() { return default_memory_pool(); } | |
32 | }; | |
33 | ||
34 | struct SystemMemoryPoolFactory { | |
35 | static MemoryPool* memory_pool() { return system_memory_pool(); } | |
36 | }; | |
37 | ||
38 | #ifdef ARROW_JEMALLOC | |
39 | struct JemallocMemoryPoolFactory { | |
40 | static MemoryPool* memory_pool() { | |
41 | MemoryPool* pool; | |
42 | ABORT_NOT_OK(jemalloc_memory_pool(&pool)); | |
43 | return pool; | |
44 | } | |
45 | }; | |
46 | #endif | |
47 | ||
48 | #ifdef ARROW_MIMALLOC | |
49 | struct MimallocMemoryPoolFactory { | |
50 | static MemoryPool* memory_pool() { | |
51 | MemoryPool* pool; | |
52 | ABORT_NOT_OK(mimalloc_memory_pool(&pool)); | |
53 | return pool; | |
54 | } | |
55 | }; | |
56 | #endif | |
57 | ||
58 | template <typename Factory> | |
59 | class TestMemoryPool : public ::arrow::TestMemoryPoolBase { | |
60 | public: | |
61 | MemoryPool* memory_pool() override { return Factory::memory_pool(); } | |
62 | }; | |
63 | ||
64 | TYPED_TEST_SUITE_P(TestMemoryPool); | |
65 | ||
66 | TYPED_TEST_P(TestMemoryPool, MemoryTracking) { this->TestMemoryTracking(); } | |
67 | ||
68 | TYPED_TEST_P(TestMemoryPool, OOM) { | |
69 | #ifndef ADDRESS_SANITIZER | |
70 | this->TestOOM(); | |
71 | #endif | |
72 | } | |
73 | ||
74 | TYPED_TEST_P(TestMemoryPool, Reallocate) { this->TestReallocate(); } | |
75 | ||
76 | REGISTER_TYPED_TEST_SUITE_P(TestMemoryPool, MemoryTracking, OOM, Reallocate); | |
77 | ||
78 | INSTANTIATE_TYPED_TEST_SUITE_P(Default, TestMemoryPool, DefaultMemoryPoolFactory); | |
79 | INSTANTIATE_TYPED_TEST_SUITE_P(System, TestMemoryPool, SystemMemoryPoolFactory); | |
80 | ||
81 | #ifdef ARROW_JEMALLOC | |
82 | INSTANTIATE_TYPED_TEST_SUITE_P(Jemalloc, TestMemoryPool, JemallocMemoryPoolFactory); | |
83 | #endif | |
84 | ||
85 | #ifdef ARROW_MIMALLOC | |
86 | INSTANTIATE_TYPED_TEST_SUITE_P(Mimalloc, TestMemoryPool, MimallocMemoryPoolFactory); | |
87 | #endif | |
88 | ||
89 | TEST(DefaultMemoryPool, Identity) { | |
90 | // The default memory pool is pointer-identical to one of the backend-specific pools. | |
91 | MemoryPool* pool = default_memory_pool(); | |
92 | std::vector<MemoryPool*> specific_pools = {system_memory_pool()}; | |
93 | #ifdef ARROW_JEMALLOC | |
94 | specific_pools.push_back(nullptr); | |
95 | ASSERT_OK(jemalloc_memory_pool(&specific_pools.back())); | |
96 | #endif | |
97 | #ifdef ARROW_MIMALLOC | |
98 | specific_pools.push_back(nullptr); | |
99 | ASSERT_OK(mimalloc_memory_pool(&specific_pools.back())); | |
100 | #endif | |
101 | ASSERT_NE(std::find(specific_pools.begin(), specific_pools.end(), pool), | |
102 | specific_pools.end()); | |
103 | } | |
104 | ||
105 | // Death tests and valgrind are known to not play well 100% of the time. See | |
106 | // googletest documentation | |
107 | #if !(defined(ARROW_VALGRIND) || defined(ADDRESS_SANITIZER)) | |
108 | ||
109 | TEST(DefaultMemoryPoolDeathTest, MaxMemory) { | |
110 | MemoryPool* pool = default_memory_pool(); | |
111 | uint8_t* data1; | |
112 | uint8_t* data2; | |
113 | ||
114 | ASSERT_OK(pool->Allocate(100, &data1)); | |
115 | ASSERT_OK(pool->Allocate(50, &data2)); | |
116 | pool->Free(data2, 50); | |
117 | ASSERT_OK(pool->Allocate(100, &data2)); | |
118 | pool->Free(data1, 100); | |
119 | pool->Free(data2, 100); | |
120 | ||
121 | ASSERT_EQ(200, pool->max_memory()); | |
122 | } | |
123 | ||
124 | #endif // ARROW_VALGRIND | |
125 | ||
126 | TEST(LoggingMemoryPool, Logging) { | |
127 | auto pool = MemoryPool::CreateDefault(); | |
128 | ||
129 | LoggingMemoryPool lp(pool.get()); | |
130 | ||
131 | uint8_t* data; | |
132 | ASSERT_OK(lp.Allocate(100, &data)); | |
133 | ||
134 | uint8_t* data2; | |
135 | ASSERT_OK(lp.Allocate(100, &data2)); | |
136 | ||
137 | lp.Free(data, 100); | |
138 | lp.Free(data2, 100); | |
139 | ||
140 | ASSERT_EQ(200, lp.max_memory()); | |
141 | ASSERT_EQ(200, pool->max_memory()); | |
142 | } | |
143 | ||
144 | TEST(ProxyMemoryPool, Logging) { | |
145 | auto pool = MemoryPool::CreateDefault(); | |
146 | ||
147 | ProxyMemoryPool pp(pool.get()); | |
148 | ||
149 | uint8_t* data; | |
150 | ASSERT_OK(pool->Allocate(100, &data)); | |
151 | ||
152 | uint8_t* data2; | |
153 | ASSERT_OK(pp.Allocate(300, &data2)); | |
154 | ||
155 | ASSERT_EQ(400, pool->bytes_allocated()); | |
156 | ASSERT_EQ(300, pp.bytes_allocated()); | |
157 | ||
158 | pool->Free(data, 100); | |
159 | pp.Free(data2, 300); | |
160 | ||
161 | ASSERT_EQ(0, pool->bytes_allocated()); | |
162 | ASSERT_EQ(0, pp.bytes_allocated()); | |
163 | } | |
164 | ||
165 | TEST(Jemalloc, SetDirtyPageDecayMillis) { | |
166 | // ARROW-6910 | |
167 | #ifdef ARROW_JEMALLOC | |
168 | ASSERT_OK(jemalloc_set_decay_ms(0)); | |
169 | #else | |
170 | ASSERT_RAISES(Invalid, jemalloc_set_decay_ms(0)); | |
171 | #endif | |
172 | } | |
173 | ||
174 | } // namespace arrow |