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