• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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