1/*
2 * Copyright (c) 2021 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
16namespace OHOS {
17namespace AI {
18template<class TYPE>
19std::mutex QueuePool<TYPE>::mutex_;
20
21template<class TYPE>
22QueuePool<TYPE> *QueuePool<TYPE>::instance_ = nullptr;
23
24template<class TYPE>
25size_t QueuePool<TYPE>::singleQueueCapacity_ = MAX_QUEUE_LENGTH;
26
27template<class TYPE>
28QueuePool<TYPE> *QueuePool<TYPE>::GetInstance(size_t singleQueueCapacity) {
29    CHK_RET(instance_ != nullptr, instance_);
30
31    std::lock_guard<std::mutex> lock(mutex_);
32    CHK_RET(instance_ != nullptr, instance_);
33
34    singleQueueCapacity_ = singleQueueCapacity;
35    AIE_NEW(instance_, QueuePool<TYPE>);
36
37    return instance_;
38}
39
40template<class TYPE>
41void QueuePool<TYPE>::ReleaseInstance() {
42    std::lock_guard<std::mutex> lock(mutex_);
43
44    AIE_DELETE(instance_);
45}
46
47template<class TYPE>
48QueuePool<TYPE>::QueuePool()
49        : busyQueueNum_(0) {
50}
51
52template<class TYPE>
53QueuePool<TYPE>::~QueuePool() = default;
54
55template<class TYPE>
56std::shared_ptr<Queue<TYPE>> QueuePool<TYPE>::Pop() {
57    std::shared_ptr <Queue<TYPE>> queue = nullptr;
58
59    if (busyQueueNum_ >= MAX_QUEUE_COUNT) {
60        return queue;
61    }
62
63    ++busyQueueNum_;
64
65    if (queues_.empty()) {
66        Queue<TYPE> *ptr = nullptr;
67        AIE_NEW(ptr, Queue<TYPE>(singleQueueCapacity_));
68        CHK_RET(ptr == nullptr, nullptr);
69        queue.reset(ptr);
70
71        return queue;
72    }
73
74    std::lock_guard<std::mutex> guard(mutex4Inner_);
75    queue = queues_.front();
76    queues_.pop_front();
77
78    return queue;
79}
80
81template<class TYPE>
82void QueuePool<TYPE>::Push(std::shared_ptr<Queue<TYPE>> &queue) {
83    if (busyQueueNum_ <= 0) {
84        return;
85    }
86
87    busyQueueNum_--;
88
89    std::lock_guard<std::mutex> guard(mutex4Inner_);
90    queue->Reset();
91    queues_.push_back(queue);
92}
93
94template<class TYPE>
95size_t QueuePool<TYPE>::BusyQueueNum() const {
96    return busyQueueNum_;
97}
98} // namespace AI
99} // namespace OHOS