OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
buffer_pool.hpp
1#pragma once
2#include <ossia/detail/pod_vector.hpp>
3#include <ossia/detail/lockfree_queue.hpp>
4
5namespace ossia
6{
7template <typename Obj_T>
8struct object_pool
9{
10 mpmc_queue<Obj_T> buffers;
11
12 Obj_T acquire()
13 {
14 Obj_T b;
15 buffers.try_dequeue(b);
16 return b;
17 }
18
19 void release(Obj_T b) { buffers.enqueue(std::move(b)); }
20};
21
22// TODO categorized_object_pool with more generic user-defined categorization ?
23
24// given
25// std::integer_sequence<int, 10, 100, 1000>;
26// queues[0]: size € [0 , 9]
27// queues[1]: size € [10, 99]
28// queues[2]: size € [100, 999]
29// queues[3]: size € [1000, +oo[
30
31template <typename Obj_T, typename Alloc, std::size_t... sz>
32struct sized_object_pool
33{
34 using SizeSpec = std::integer_sequence<std::size_t, sz...>;
35
36 static const constexpr auto buckets = SizeSpec::size() + 1;
37 std::array<mpmc_queue<Obj_T>, buckets> queues;
38
39 template <std::size_t Sz, std::size_t... Szs>
40 static constexpr int find_bucket_impl(std::size_t size, std::size_t k) noexcept
41 {
42 if(size < Sz)
43 return k;
44 else if constexpr(sizeof...(Szs) > 0)
45 return find_bucket_impl<Szs...>(size, k + 1);
46 else
47 return k + 1;
48 }
49
50 static constexpr int find_bucket(std::size_t size) noexcept
51 {
52 return find_bucket_impl<sz...>(size, 0);
53 }
54
55 Obj_T acquire_sized(std::size_t req_size = 1024) noexcept
56 {
57 Obj_T b;
58 if(!queues[find_bucket(req_size)].try_dequeue(b))
59 {
60 Alloc::resize(b, req_size);
61 }
62 return b;
63 }
64
65 Obj_T acquire_reserved(std::size_t req_size = 1024) noexcept
66 {
67 Obj_T b;
68 if(!queues[find_bucket(req_size)].try_dequeue(b))
69 {
70 Alloc::reserve(b, req_size);
71 }
72 return b;
73 }
74
75 void release(Obj_T b) noexcept
76 {
77 queues[find_bucket(Alloc::size(b))].enqueue(std::move(b));
78 }
79
80 static sized_object_pool& instance() noexcept
81 {
82 static sized_object_pool p;
83 return p;
84 }
85};
86
87template <typename T>
88struct container_memory_manager
89{
90 static constexpr void resize(T& t, std::size_t sz) noexcept { t.resize(sz); }
91 static constexpr void reserve(T& t, std::size_t sz) noexcept { t.reserve(sz); }
92 static constexpr std::size_t size(const T& t) noexcept { return t.size(); }
93};
94
95struct buffer_pool
96{
97 using buffer = ossia::pod_vector<char>;
98
99 mpmc_queue<buffer> buffers;
100
101 buffer acquire(std::size_t req_size = 1024)
102 {
103 buffer b;
104
105 buffers.try_dequeue(b);
106 b.resize(req_size, boost::container::default_init);
107 return b;
108 }
109
110 void release(buffer b)
111 {
112 b.clear();
113 buffers.enqueue(std::move(b));
114 }
115
116 static buffer_pool& instance()
117 {
118 static buffer_pool p;
119 return p;
120 }
121};
122
123}
Definition git_info.h:7