memory_allocators.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #pragma once
  6. #include <atomic>
  7. #include "rocksdb/memory_allocator.h"
  8. namespace ROCKSDB_NAMESPACE {
  9. // A memory allocator using new/delete
  10. class DefaultMemoryAllocator : public MemoryAllocator {
  11. public:
  12. static const char* kClassName() { return "DefaultMemoryAllocator"; }
  13. const char* Name() const override { return kClassName(); }
  14. void* Allocate(size_t size) override {
  15. return static_cast<void*>(new char[size]);
  16. }
  17. void Deallocate(void* p) override { delete[] static_cast<char*>(p); }
  18. };
  19. // Base class for a MemoryAllocator. This implementation does nothing
  20. // and implements the methods in failuse mode (assert if the methods are
  21. // invoked). Implementations can extend this class and override these methods
  22. // when they are enabled via compiler switches (e.g., the
  23. // JeMallocMemoryAllocator can define these methods if ROCKSDB_JEMALLOC is
  24. // defined at compile time. If compiled in "disabled" mode, this class provides
  25. // default/failure implementations. If compiled in "enabled" mode, the derived
  26. // class needs to provide the appopriate "enabled" methods for the "real"
  27. // implementation. Failure of the "real" implementation to implement ovreride
  28. // any of these methods will result in an assert failure.
  29. class BaseMemoryAllocator : public MemoryAllocator {
  30. public:
  31. void* Allocate(size_t /*size*/) override {
  32. assert(false);
  33. return nullptr;
  34. }
  35. void Deallocate(void* /*p*/) override { assert(false); }
  36. };
  37. // A Wrapped MemoryAllocator. Delegates the memory allcator functions to the
  38. // wrapped one.
  39. class MemoryAllocatorWrapper : public MemoryAllocator {
  40. public:
  41. // Initialize an MemoryAllocatorWrapper that delegates all calls to *t
  42. explicit MemoryAllocatorWrapper(const std::shared_ptr<MemoryAllocator>& t);
  43. ~MemoryAllocatorWrapper() override {}
  44. // Return the target to which to forward all calls
  45. MemoryAllocator* target() const { return target_.get(); }
  46. // Allocate a block of at least size. Has to be thread-safe.
  47. void* Allocate(size_t size) override { return target_->Allocate(size); }
  48. // Deallocate previously allocated block. Has to be thread-safe.
  49. void Deallocate(void* p) override { return target_->Deallocate(p); }
  50. // Returns the memory size of the block allocated at p. The default
  51. // implementation that just returns the original allocation_size is fine.
  52. size_t UsableSize(void* p, size_t allocation_size) const override {
  53. return target_->UsableSize(p, allocation_size);
  54. }
  55. const Customizable* Inner() const override { return target_.get(); }
  56. protected:
  57. std::shared_ptr<MemoryAllocator> target_;
  58. };
  59. // A memory allocator that counts the number of allocations and deallocations
  60. // This class is useful if the number of memory allocations/dellocations is
  61. // important.
  62. class CountedMemoryAllocator : public MemoryAllocatorWrapper {
  63. public:
  64. CountedMemoryAllocator()
  65. : MemoryAllocatorWrapper(std::make_shared<DefaultMemoryAllocator>()),
  66. allocations_(0),
  67. deallocations_(0) {}
  68. explicit CountedMemoryAllocator(const std::shared_ptr<MemoryAllocator>& t)
  69. : MemoryAllocatorWrapper(t), allocations_(0), deallocations_(0) {}
  70. static const char* kClassName() { return "CountedMemoryAllocator"; }
  71. const char* Name() const override { return kClassName(); }
  72. std::string GetId() const override { return std::string(Name()); }
  73. void* Allocate(size_t size) override {
  74. allocations_++;
  75. return MemoryAllocatorWrapper::Allocate(size);
  76. }
  77. void Deallocate(void* p) override {
  78. deallocations_++;
  79. MemoryAllocatorWrapper::Deallocate(p);
  80. }
  81. uint64_t GetNumAllocations() const { return allocations_; }
  82. uint64_t GetNumDeallocations() const { return deallocations_; }
  83. private:
  84. std::atomic<uint64_t> allocations_;
  85. std::atomic<uint64_t> deallocations_;
  86. };
  87. } // namespace ROCKSDB_NAMESPACE