1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#ifndef LIBPANDABASE_MEM_MEM_POOL_H
17b1994897Sopenharmony_ci#define LIBPANDABASE_MEM_MEM_POOL_H
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include <cstddef>
20b1994897Sopenharmony_ci#include "macros.h"
21b1994897Sopenharmony_ci#include "mem.h"
22b1994897Sopenharmony_ci#include "pool_map.h"
23b1994897Sopenharmony_ci
24b1994897Sopenharmony_cinamespace panda {
25b1994897Sopenharmony_ciclass Arena;
26b1994897Sopenharmony_ci
27b1994897Sopenharmony_ciclass Pool {
28b1994897Sopenharmony_cipublic:
29b1994897Sopenharmony_ci    explicit constexpr Pool(size_t size, void *mem) : size_(size), mem_(mem) {}
30b1994897Sopenharmony_ci    explicit Pool(std::pair<size_t, void *> pool) : size_(pool.first), mem_(pool.second) {}
31b1994897Sopenharmony_ci
32b1994897Sopenharmony_ci    size_t GetSize() const
33b1994897Sopenharmony_ci    {
34b1994897Sopenharmony_ci        return size_;
35b1994897Sopenharmony_ci    }
36b1994897Sopenharmony_ci
37b1994897Sopenharmony_ci    void *GetMem()
38b1994897Sopenharmony_ci    {
39b1994897Sopenharmony_ci        return mem_;
40b1994897Sopenharmony_ci    }
41b1994897Sopenharmony_ci
42b1994897Sopenharmony_ci    bool operator==(const Pool &other) const
43b1994897Sopenharmony_ci    {
44b1994897Sopenharmony_ci        return (this->size_ == other.size_) && (this->mem_ == other.mem_);
45b1994897Sopenharmony_ci    }
46b1994897Sopenharmony_ci
47b1994897Sopenharmony_ci    bool operator!=(const Pool &other) const
48b1994897Sopenharmony_ci    {
49b1994897Sopenharmony_ci        return !(*this == other);
50b1994897Sopenharmony_ci    }
51b1994897Sopenharmony_ci
52b1994897Sopenharmony_ci    ~Pool() = default;
53b1994897Sopenharmony_ci
54b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(Pool);
55b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(Pool);
56b1994897Sopenharmony_ci
57b1994897Sopenharmony_ciprivate:
58b1994897Sopenharmony_ci    size_t size_;
59b1994897Sopenharmony_ci    void *mem_;
60b1994897Sopenharmony_ci};
61b1994897Sopenharmony_ci
62b1994897Sopenharmony_ciconstexpr Pool NULLPOOL {0, nullptr};
63b1994897Sopenharmony_ci
64b1994897Sopenharmony_citemplate <class MemPoolImplT>
65b1994897Sopenharmony_ciclass MemPool {
66b1994897Sopenharmony_cipublic:
67b1994897Sopenharmony_ci    virtual ~MemPool() = default;
68b1994897Sopenharmony_ci    explicit MemPool(std::string pool_name) : name_(std::move(pool_name)) {}
69b1994897Sopenharmony_ci    DEFAULT_NOEXCEPT_MOVE_SEMANTIC(MemPool);
70b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(MemPool);
71b1994897Sopenharmony_ci
72b1994897Sopenharmony_ci    /**
73b1994897Sopenharmony_ci     * Allocates arena with size bytes
74b1994897Sopenharmony_ci     * @tparam ArenaT - type of Arena
75b1994897Sopenharmony_ci     * @param size - size of buffer in arena in bytes
76b1994897Sopenharmony_ci     * @param space_type - type of the space which arena allocated for
77b1994897Sopenharmony_ci     * @param allocator_type - type of the allocator which arena allocated for
78b1994897Sopenharmony_ci     * @param allocator_addr - address of the allocator header.
79b1994897Sopenharmony_ci     * @return pointer to allocated arena
80b1994897Sopenharmony_ci     */
81b1994897Sopenharmony_ci    // TODO(aemelenko): We must always define allocator_addr for AllocArena
82b1994897Sopenharmony_ci    // because we set up arena at the first bytes of the pool
83b1994897Sopenharmony_ci    template <class ArenaT = Arena>
84b1994897Sopenharmony_ci    inline ArenaT *AllocArena(size_t size, SpaceType space_type, AllocatorType allocator_type,
85b1994897Sopenharmony_ci                              const void *allocator_addr = nullptr)
86b1994897Sopenharmony_ci    {
87b1994897Sopenharmony_ci        return static_cast<MemPoolImplT *>(this)->template AllocArenaImpl<ArenaT>(size, space_type, allocator_type,
88b1994897Sopenharmony_ci                                                                                  allocator_addr);
89b1994897Sopenharmony_ci    }
90b1994897Sopenharmony_ci
91b1994897Sopenharmony_ci    /**
92b1994897Sopenharmony_ci     * Frees allocated arena
93b1994897Sopenharmony_ci     * @tparam ArenaT - arena type
94b1994897Sopenharmony_ci     * @param arena - pointer to the arena
95b1994897Sopenharmony_ci     */
96b1994897Sopenharmony_ci    template <class ArenaT = Arena>
97b1994897Sopenharmony_ci    inline void FreeArena(ArenaT *arena)
98b1994897Sopenharmony_ci    {
99b1994897Sopenharmony_ci        static_cast<MemPoolImplT *>(this)->template FreeArenaImpl<ArenaT>(arena);
100b1994897Sopenharmony_ci    }
101b1994897Sopenharmony_ci
102b1994897Sopenharmony_ci    /**
103b1994897Sopenharmony_ci     * Allocates pool with at least size bytes
104b1994897Sopenharmony_ci     * @param size - minimal size of a pool in bytes
105b1994897Sopenharmony_ci     * @param space_type - type of the space which pool allocated for
106b1994897Sopenharmony_ci     * @param allocator_type - type of the allocator which arena allocated for
107b1994897Sopenharmony_ci     * @param allocator_addr - address of the allocator header.
108b1994897Sopenharmony_ci     *  If it is not defined, it means that allocator header will be located at the first bytes of the returned pool.
109b1994897Sopenharmony_ci     * @return pool info with the size and a pointer
110b1994897Sopenharmony_ci     */
111b1994897Sopenharmony_ci    Pool AllocPool(size_t size, SpaceType space_type, AllocatorType allocator_type,
112b1994897Sopenharmony_ci                   const void *allocator_addr = nullptr)
113b1994897Sopenharmony_ci    {
114b1994897Sopenharmony_ci        return static_cast<MemPoolImplT *>(this)->AllocPoolImpl(size, space_type, allocator_type, allocator_addr);
115b1994897Sopenharmony_ci    }
116b1994897Sopenharmony_ci
117b1994897Sopenharmony_ci    /**
118b1994897Sopenharmony_ci     * Frees allocated pool
119b1994897Sopenharmony_ci     * @param mem - pointer to an allocated pool
120b1994897Sopenharmony_ci     * @param size - size of the allocated pool in bytes
121b1994897Sopenharmony_ci     */
122b1994897Sopenharmony_ci    void FreePool(void *mem, size_t size)
123b1994897Sopenharmony_ci    {
124b1994897Sopenharmony_ci        static_cast<MemPoolImplT *>(this)->FreePoolImpl(mem, size);
125b1994897Sopenharmony_ci    }
126b1994897Sopenharmony_ci
127b1994897Sopenharmony_ci    /**
128b1994897Sopenharmony_ci     * Get info about the allocator in which this address is used
129b1994897Sopenharmony_ci     * @param addr
130b1994897Sopenharmony_ci     * @return Allocator info with a type and pointer to the allocator header
131b1994897Sopenharmony_ci     */
132b1994897Sopenharmony_ci    AllocatorInfo GetAllocatorInfoForAddr(const void *addr) const
133b1994897Sopenharmony_ci    {
134b1994897Sopenharmony_ci        return static_cast<const MemPoolImplT *>(this)->GetAllocatorInfoForAddrImpl(addr);
135b1994897Sopenharmony_ci    }
136b1994897Sopenharmony_ci
137b1994897Sopenharmony_ci    /**
138b1994897Sopenharmony_ci     * Get space type which this address used for
139b1994897Sopenharmony_ci     * @param addr
140b1994897Sopenharmony_ci     * @return space type
141b1994897Sopenharmony_ci     */
142b1994897Sopenharmony_ci    SpaceType GetSpaceTypeForAddr(const void *addr) const
143b1994897Sopenharmony_ci    {
144b1994897Sopenharmony_ci        return static_cast<const MemPoolImplT *>(this)->GetSpaceTypeForAddrImpl(addr);
145b1994897Sopenharmony_ci    }
146b1994897Sopenharmony_ci
147b1994897Sopenharmony_ci    /**
148b1994897Sopenharmony_ci     * Get address of pool start for input address
149b1994897Sopenharmony_ci     * @param addr address in pool
150b1994897Sopenharmony_ci     * @return address of pool start
151b1994897Sopenharmony_ci     */
152b1994897Sopenharmony_ci    void *GetStartAddrPoolForAddr(const void *addr) const
153b1994897Sopenharmony_ci    {
154b1994897Sopenharmony_ci        return static_cast<const MemPoolImplT *>(this)->GetStartAddrPoolForAddrImpl(addr);
155b1994897Sopenharmony_ci    }
156b1994897Sopenharmony_ci
157b1994897Sopenharmony_ciprivate:
158b1994897Sopenharmony_ci    std::string name_;
159b1994897Sopenharmony_ci};
160b1994897Sopenharmony_ci
161b1994897Sopenharmony_ci}  // namespace panda
162b1994897Sopenharmony_ci
163b1994897Sopenharmony_ci#endif  // LIBPANDABASE_MEM_MEM_POOL_H
164