Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
object_pool.h
1// SPDX-FileCopyrightText: © 2024 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <memory>
7#include <vector>
8
9#include "utils/mpmc_queue.h"
10
16
17template <typename T, bool EnableDebug = false>
18class [[deprecated ("Use a pre-filled MPMCQueue instead")]] ObjectPool
19{
20public:
21 static_assert (
22 std::is_default_constructible_v<T>,
23 "T must be default-constructible");
24
25 ObjectPool (size_t initial_capacity = 64) { reserve (initial_capacity); }
26
27 T * acquire ()
28 {
29 T * object;
30 if (available_.pop_front (object))
31 {
32 if constexpr (EnableDebug)
33 {
34 num_in_use.fetch_add (1, std::memory_order_relaxed);
35 }
36 return object;
37 }
38
39 if (size_ == capacity_)
40 {
41 expand ();
42 }
43
44 return acquire ();
45 }
46
47 void release (T * object)
48 {
49 available_.push_back (object);
50 if constexpr (EnableDebug)
51 {
52 num_in_use.fetch_add (-1);
53 }
54 }
55
56 void reserve (size_t size)
57 {
58 available_.reserve (size);
59 while (size_ < size)
60 {
61 expand ();
62 }
63 }
64
65 auto get_num_in_use () const { return num_in_use.load (); }
66 auto get_capacity () const { return capacity_.load (); }
67 auto get_size () const { return size_.load (); }
68
69private:
70 void expand ()
71 {
72 std::lock_guard<std::mutex> lock (expand_mutex_);
73
74 // Check again after acquiring lock in case another thread already expanded
75 if (size_ == capacity_)
76 {
77 size_t old_capacity = capacity_;
78 if (capacity_ == 0)
79 {
80 capacity_ = 1;
81 }
82 capacity_.store (capacity_ * 2);
83
84 buffer_.reserve (capacity_);
85
86 for (size_t i = old_capacity; i < capacity_; ++i)
87 {
88 buffer_.emplace_back (std::make_unique<T> ());
89 available_.push_back (buffer_.back ().get ());
90 }
91
92 size_.store (capacity_.load ());
93 }
94 }
95
96 std::vector<std::unique_ptr<T>> buffer_;
97 MPMCQueue<T *> available_;
98 std::atomic<size_t> capacity_{ 0 };
99 std::atomic<size_t> size_{ 0 };
100 std::mutex expand_mutex_;
101
102 // Debug counter
103 std::atomic<size_t> num_in_use;
104};
Multiple Producer Multiple Consumer lock-free queue.
Definition mpmc_queue.h:65