1 /** 2 * Copyright 2019 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_UTIL_BUDDY_H_ 17 #define MINDSPORE_CCSRC_MINDDATA_DATASET_UTIL_BUDDY_H_ 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <cstring> 22 #include <iostream> 23 #include <memory> 24 #include <mutex> 25 #include "minddata/dataset/util/status.h" 26 27 using addr_t = int64_t; 28 using rel_addr_t = int32_t; 29 using log_t = int; 30 #define ALLOC_BIT 0x80 31 #define ONE_BIT 0x40 32 #define TWO_BIT 0x20 33 #define MORE_BIT 0x10 34 #define NOSPACE ((addr_t)(-1)) 35 namespace mindspore { 36 namespace dataset { 37 struct BSpaceDescriptor { 38 int32_t sig; 39 rel_addr_t addr; 40 size_t req_size; 41 size_t blk_size; 42 }; 43 44 class BuddySpace { 45 public: 46 // C++11 feature. Change STATE into a type safe class with 47 // the keyword. Don't take out the keyword 'class' 48 enum class STATE { kFree, kAlloc, kEmpty }; 49 50 BuddySpace(const BuddySpace &) = delete; 51 52 BuddySpace &operator=(const BuddySpace &) = delete; 53 54 virtual ~BuddySpace(); 55 56 Status Alloc(uint64_t sz, BSpaceDescriptor *desc, addr_t *) noexcept; 57 58 void Free(const BSpaceDescriptor *desc); 59 GetMinSize()60 uint64_t GetMinSize() const { return min_; } 61 GetMaxSize()62 uint64_t GetMaxSize() const { return max_; } 63 64 int PercentFree() const; 65 66 friend std::ostream &operator<<(std::ostream &os, const BuddySpace &s); 67 NextPowerOf2(uint64_t n)68 static uint64_t NextPowerOf2(uint64_t n) { 69 if (n <= 1) { 70 return 1; 71 } 72 n = n - 1; 73 while (n & (n - 1)) { 74 n = n & (n - 1); 75 } 76 return n << 1; 77 } 78 Log2(uint64_t n)79 static uint32_t Log2(uint64_t n) { 80 uint32_t cnt = 0; 81 while (n >>= 1) { 82 cnt++; 83 } 84 return cnt; 85 } 86 87 static Status CreateBuddySpace(std::unique_ptr<BuddySpace> *out_bs, int log_min = 15, int num_lvl = 18); 88 89 private: 90 rel_addr_t *hint_; 91 int *count_; 92 char *map_; 93 int log_min_; 94 int num_lvl_; 95 uint64_t min_; 96 uint64_t max_; 97 std::unique_ptr<uint8_t[]> mem_; 98 std::mutex mutex_; 99 100 explicit BuddySpace(int log_min = 15, int num_lvl = 18); 101 102 Status Init(); 103 104 addr_t AllocNoLock(const uint64_t sz, BSpaceDescriptor *desc) noexcept; 105 106 void FreeNoLock(const BSpaceDescriptor *desc); 107 108 uint32_t SizeToBlock(const uint64_t sz) const; 109 110 void GetBuddySegState(const rel_addr_t rel_addr, size_t *rel_sz, STATE *st) const; 111 112 void SetBuddySegState(rel_addr_t rel_addr, size_t rel_sz, STATE st); 113 114 void JoinBuddySeg(rel_addr_t addr, size_t blk_sz); 115 116 void TrimBuddySeg(rel_addr_t addr, size_t blk_sz, size_t ask_sz); 117 118 void UnTrimBuddySeg(rel_addr_t addr, size_t blk_sz, size_t ask_sz); 119 120 rel_addr_t AllocBuddySeg(uint32_t req_size) noexcept; 121 122 void FreeBuddySeg(rel_addr_t addr, size_t blk_size, size_t req_size); 123 }; 124 } // namespace dataset 125 } // namespace mindspore 126 127 #endif // MINDSPORE_CCSRC_MINDDATA_DATASET_UTIL_BUDDY_H_ 128