1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef AVSHAREDMEMORYPOOL_H
17 #define AVSHAREDMEMORYPOOL_H
18 
19 #include <condition_variable>
20 #include <functional>
21 #include <list>
22 #include <memory>
23 #include <mutex>
24 #include "nocopyable.h"
25 #include "buffer/avsharedmemorybase.h"
26 
27 namespace OHOS {
28 namespace Media {
29 /**
30  * @brief A simple pool implementation for shared memory.
31  *
32  * This pool support multi configuration:
33  * @preAllocMemCnt: The number of memory blocks allocated when the pool is initialized.
34  * @memSize: the size of the preallocated memory blocks.
35  * @maxMemCnt: the total number of memory blocks in the pool.
36  * @flags: the shared memory access property, refer to {@AVSharedMemory::Flags}.
37  * @enableFixedSize: if true, the pool will allocate all memory block using the memSize. If the acquired
38  *                  size is larger than the memSize, the acquire will failed. If false, the pool will
39  *                  free the smallest idle memory block when there is no idle memory block that can
40  *                  satisfy the acqiured size and reallocate a new memory block with the acquired size.
41  * @notifier: the callback will be called to notify there are any available memory. It will be useful for
42  *            non-blocking memory acquisition.
43  */
44 class AVSharedMemoryPool : public std::enable_shared_from_this<AVSharedMemoryPool>, public NoCopyable {
45 public:
46     explicit AVSharedMemoryPool(const std::string &name);
47     ~AVSharedMemoryPool();
48 
49     using MemoryAvailableNotifier = std::function<void(void)>;
50 
51     struct InitializeOption {
52         uint32_t preAllocMemCnt = 0;
53         int32_t memSize = 0;
54         uint32_t maxMemCnt = 0;
55         uint32_t flags = AVSharedMemory::Flags::FLAGS_READ_WRITE;
56         bool enableFixedSize = true;
57         MemoryAvailableNotifier notifier;
58     };
59 
60     /**
61      * @brief Initialize the pool and preallocate some memory blocks.
62      */
63     int32_t Init(const InitializeOption &option);
64 
65     /**
66      * @brief Get a memory from the pool and optional to wait for a memory to be release when there
67      * are no memories available.
68      *
69      * @param size the expected memory size. if the enableFixedSize is configured, this param can be empty.
70      * @return valid memory block if success, or nullptr.
71      */
72     std::shared_ptr<AVSharedMemory> AcquireMemory(int32_t size = -1, bool blocking = true);
73 
74     /**
75      * @brief Set or Unset the pool to be non-blocking memory pool. If enable, the AcquireMemory will always
76      * be non-blocking and the waiters will be returned with null memory.
77      */
78     void SetNonBlocking(bool enable);
79 
80     /**
81      * @brief Free all memory blocks and reset the pool configuration. After reseted, all waiters of
82      * the pool will be awaken up and returned with a nullptr.
83      */
84     void Reset();
85 
GetName()86     std::string GetName()
87     {
88         return name_;
89     }
90 
91 private:
92     bool DoAcquireMemory(int32_t size, AVSharedMemory **outMemory);
93     AVSharedMemory *AllocMemory(int32_t size);
94     void ReleaseMemory(AVSharedMemory *memory);
95     bool CheckSize(int32_t size);
96 
97     InitializeOption option_ {};
98     std::list<AVSharedMemory *> idleList_;
99     std::list<AVSharedMemory *> busyList_;
100     std::mutex mutex_;
101     std::condition_variable cond_;
102     bool inited_ = false;
103     std::string name_;
104     MemoryAvailableNotifier notifier_;
105     bool forceNonBlocking_ = false;
106 };
107 } // namespace Media
108 } // namespace OHOS
109 
110 #endif