util/mem; use a pool for playtime allocations

master
Zithia Satazaki 2022-03-28 16:15:55 -04:00
parent 15c0aaed82
commit acbba0403b
3 changed files with 76 additions and 5 deletions

View File

@ -8,6 +8,8 @@
#include "data/node.h"
#include "util/mem.h"
namespace Xybrid::Data {
class CommandPort;
class AudioPort;
@ -23,9 +25,6 @@ namespace Xybrid::NodeLib {
* Not mandatory by any means, but handles all the "standard" commands for you.
*/
class InstrumentCore {
double time;
double smpTime;
public:
class Note {
friend class InstrumentCore;
@ -50,6 +49,8 @@ namespace Xybrid::NodeLib {
std::array<void*, 5> ptr;
};
template<typename T> inline T& scratchAs() { return *(reinterpret_cast<T*>(reinterpret_cast<void*>(&scratch))); }
Note() = default;
Note(InstrumentCore*, uint16_t id);
@ -79,12 +80,19 @@ namespace Xybrid::NodeLib {
void startTick(Note&, double tickTime);
void process(Note&, double smpTime);
};
private:
//
double time;
double smpTime;
public:
double volume = 1.0;
double pan = 0.0;
std::unordered_map<uint16_t, Note> activeNotes;
std::unordered_multimap<uint16_t, Tween> activeTweens;
std::pmr::unordered_map<uint16_t, Note> activeNotes = {16, Util::ralloc};
std::pmr::unordered_multimap<uint16_t, Tween> activeTweens = {16, Util::ralloc};
std::function<bool(Note*, const ParamReader&)> paramFilter;
std::unordered_map<uint8_t, std::function<bool(const ParamReader&)>> globalParam;

15
xybrid/util/mem.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "mem.h"
using namespace Xybrid::Util;
std::pmr::synchronized_pool_resource Xybrid::Util::rpool; // instantiate
decltype(Xybrid::Util::ralloc) Xybrid::Util::ralloc(&rpool);
namespace {
static bool _____ = [] { // static init hackery to force pre-reservation of a certain chunk size
const constexpr size_t rsize = 1024*1024*128;
auto r = rpool.allocate(rsize);
rpool.deallocate(r, rsize);
return false;
}();
}

48
xybrid/util/mem.h Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include <cstddef>
#include <list>
#include <deque>
#include <memory_resource>
#include <unordered_set>
namespace Xybrid::Util {
extern std::pmr::synchronized_pool_resource rpool;
extern std::pmr::polymorphic_allocator<std::max_align_t> ralloc;
template<typename T, size_t PSIZE = 16>
class ResourcePool {
typedef char slot[sizeof(T)];
std::list<slot[PSIZE]> pages;
std::deque<T*> avail;
std::pmr::unordered_set<T*> used = {rpool};
void newPage() {
auto p = pages.emplace_back();
for (size_t i = 0; i < PSIZE; i++) avail.push_back(&p[i]);
//avail.res
}
public:
typedef T type;
static const constexpr size_t pageSize = PSIZE;
template<typename... Arg>
T* getNew(Arg... args) {
if (avail.empty()) newPage();
T* n = avail.pop_back();
new (n) T(args...);
used.insert(n);
return n;
}
void del(T* n) {
if (!used.contains(n)) return; // not mine
n->~T(); // destroy object
used.erase(n);
avail.push_back(n);
}
};
}