File indexing completed on 2025-08-27 08:47:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #pragma once
0019
0020 #include <atomic>
0021 #include <cstdint>
0022 #include <functional>
0023 #include <memory>
0024 #include <string>
0025
0026 #include "arrow/result.h"
0027 #include "arrow/status.h"
0028 #include "arrow/type_fwd.h"
0029 #include "arrow/util/visibility.h"
0030
0031 namespace arrow {
0032
0033 namespace internal {
0034
0035
0036
0037
0038
0039
0040
0041 class alignas(64) MemoryPoolStats {
0042 private:
0043
0044
0045
0046
0047
0048 std::atomic<int64_t> max_memory_{0};
0049 std::atomic<int64_t> bytes_allocated_{0};
0050 std::atomic<int64_t> total_allocated_bytes_{0};
0051 std::atomic<int64_t> num_allocs_{0};
0052
0053 public:
0054 int64_t max_memory() const { return max_memory_.load(std::memory_order_acquire); }
0055
0056 int64_t bytes_allocated() const {
0057 return bytes_allocated_.load(std::memory_order_acquire);
0058 }
0059
0060 int64_t total_bytes_allocated() const {
0061 return total_allocated_bytes_.load(std::memory_order_acquire);
0062 }
0063
0064 int64_t num_allocations() const { return num_allocs_.load(std::memory_order_acquire); }
0065
0066 inline void DidAllocateBytes(int64_t size) {
0067
0068
0069 auto max_memory = max_memory_.load(std::memory_order_relaxed);
0070 const auto old_bytes_allocated =
0071 bytes_allocated_.fetch_add(size, std::memory_order_acq_rel);
0072
0073
0074
0075
0076
0077 total_allocated_bytes_.fetch_add(size, std::memory_order_acq_rel);
0078 num_allocs_.fetch_add(1, std::memory_order_acq_rel);
0079
0080
0081
0082 const auto allocated = old_bytes_allocated + size;
0083 while (max_memory < allocated && !max_memory_.compare_exchange_weak(
0084 max_memory, allocated,
0085 std::memory_order_acq_rel)) {
0086 }
0087 }
0088
0089 inline void DidReallocateBytes(int64_t old_size, int64_t new_size) {
0090 if (new_size > old_size) {
0091 DidAllocateBytes(new_size - old_size);
0092 } else {
0093 DidFreeBytes(old_size - new_size);
0094 }
0095 }
0096
0097 inline void DidFreeBytes(int64_t size) {
0098 bytes_allocated_.fetch_sub(size, std::memory_order_acq_rel);
0099 }
0100 };
0101
0102 }
0103
0104
0105
0106
0107
0108 class ARROW_EXPORT MemoryPool {
0109 public:
0110 virtual ~MemoryPool() = default;
0111
0112
0113 static std::unique_ptr<MemoryPool> CreateDefault();
0114
0115
0116
0117
0118 Status Allocate(int64_t size, uint8_t** out) {
0119 return Allocate(size, kDefaultBufferAlignment, out);
0120 }
0121
0122
0123 virtual Status Allocate(int64_t size, int64_t alignment, uint8_t** out) = 0;
0124
0125
0126
0127
0128
0129 virtual Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment,
0130 uint8_t** ptr) = 0;
0131 Status Reallocate(int64_t old_size, int64_t new_size, uint8_t** ptr) {
0132 return Reallocate(old_size, new_size, kDefaultBufferAlignment, ptr);
0133 }
0134
0135
0136
0137
0138
0139
0140
0141
0142 virtual void Free(uint8_t* buffer, int64_t size, int64_t alignment) = 0;
0143 void Free(uint8_t* buffer, int64_t size) {
0144 Free(buffer, size, kDefaultBufferAlignment);
0145 }
0146
0147
0148
0149
0150
0151
0152 virtual void ReleaseUnused() {}
0153
0154
0155
0156 virtual int64_t bytes_allocated() const = 0;
0157
0158
0159
0160
0161
0162 virtual int64_t max_memory() const;
0163
0164
0165 virtual int64_t total_bytes_allocated() const = 0;
0166
0167
0168 virtual int64_t num_allocations() const = 0;
0169
0170
0171 virtual std::string backend_name() const = 0;
0172
0173 protected:
0174 MemoryPool() = default;
0175 };
0176
0177 class ARROW_EXPORT LoggingMemoryPool : public MemoryPool {
0178 public:
0179 explicit LoggingMemoryPool(MemoryPool* pool);
0180 ~LoggingMemoryPool() override = default;
0181
0182 using MemoryPool::Allocate;
0183 using MemoryPool::Free;
0184 using MemoryPool::Reallocate;
0185
0186 Status Allocate(int64_t size, int64_t alignment, uint8_t** out) override;
0187 Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment,
0188 uint8_t** ptr) override;
0189 void Free(uint8_t* buffer, int64_t size, int64_t alignment) override;
0190
0191 int64_t bytes_allocated() const override;
0192
0193 int64_t max_memory() const override;
0194
0195 int64_t total_bytes_allocated() const override;
0196
0197 int64_t num_allocations() const override;
0198
0199 std::string backend_name() const override;
0200
0201 private:
0202 MemoryPool* pool_;
0203 };
0204
0205
0206
0207
0208
0209 class ARROW_EXPORT ProxyMemoryPool : public MemoryPool {
0210 public:
0211 explicit ProxyMemoryPool(MemoryPool* pool);
0212 ~ProxyMemoryPool() override;
0213
0214 using MemoryPool::Allocate;
0215 using MemoryPool::Free;
0216 using MemoryPool::Reallocate;
0217
0218 Status Allocate(int64_t size, int64_t alignment, uint8_t** out) override;
0219 Status Reallocate(int64_t old_size, int64_t new_size, int64_t alignment,
0220 uint8_t** ptr) override;
0221 void Free(uint8_t* buffer, int64_t size, int64_t alignment) override;
0222
0223 int64_t bytes_allocated() const override;
0224
0225 int64_t max_memory() const override;
0226
0227 int64_t total_bytes_allocated() const override;
0228
0229 int64_t num_allocations() const override;
0230
0231 std::string backend_name() const override;
0232
0233 private:
0234 class ProxyMemoryPoolImpl;
0235 std::unique_ptr<ProxyMemoryPoolImpl> impl_;
0236 };
0237
0238
0239 ARROW_EXPORT MemoryPool* system_memory_pool();
0240
0241
0242
0243
0244 ARROW_EXPORT Status jemalloc_memory_pool(MemoryPool** out);
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 ARROW_EXPORT
0255 Status jemalloc_set_decay_ms(int ms);
0256
0257
0258
0259
0260 ARROW_EXPORT
0261 Result<int64_t> jemalloc_get_stat(const char* name);
0262
0263
0264
0265
0266 ARROW_EXPORT
0267 Status jemalloc_peak_reset();
0268
0269
0270
0271
0272 ARROW_EXPORT
0273 Status jemalloc_stats_print(const char* opts = "");
0274
0275
0276
0277
0278 ARROW_EXPORT
0279 Status jemalloc_stats_print(std::function<void(const char*)> write_cb,
0280 const char* opts = "");
0281
0282
0283
0284
0285 ARROW_EXPORT
0286 Result<std::string> jemalloc_stats_string(const char* opts = "");
0287
0288
0289
0290
0291 ARROW_EXPORT Status mimalloc_memory_pool(MemoryPool** out);
0292
0293
0294 ARROW_EXPORT std::vector<std::string> SupportedMemoryBackendNames();
0295
0296 }