1

allow vector to be lazy init if alloc not avail

This commit is contained in:
2022-07-24 02:22:43 +02:00
parent a0fd7ea1a4
commit b0b6ec13dc
6 changed files with 54 additions and 41 deletions

View File

@ -45,7 +45,13 @@ private:
void ready(bse::unique_ptr<Thread>&& thread);
public:
Scheduler() : log("SCHED") {}
Scheduler() : log("SCHED"), ready_queue(true), block_queue(true) {} // lazy queues, wait for allocator
// The scheduler has to init the queues explicitly after the allocator is available
void init() {
ready_queue.reserve();
block_queue.reserve();
}
unsigned int get_active() const {
return (*active)->tid;

View File

@ -11,6 +11,9 @@ void Semaphore::p() {
this->lock.release();
} else {
// Block and manage thread in semaphore queue until it's woken up by v() again
if (!wait_queue.initialized()) { // TODO: I will replace this suboptimal datastructure in the future
wait_queue.reserve();
}
this->wait_queue.push_back(scheduler.get_active());
CPU::disable_int(); // Make sure the block() comes through after releasing the lock

View File

@ -27,7 +27,7 @@ private:
public:
// Konstruktor: Initialisieren des Semaphorzaehlers
Semaphore(int c) : counter(c) {}
Semaphore(int c) : wait_queue(true), counter(c) {}
// 'Passieren': Warten auf das Freiwerden eines kritischen Abschnitts.
void p();

View File

@ -46,6 +46,8 @@ int main() {
// Speicherverwaltung initialisieren
allocator.init();
scheduler.init();
kevman.init();
// Tastatur-Unterbrechungsroutine 'einstoepseln'
kb.plugin();
@ -124,6 +126,7 @@ int main() {
// DONE: Move Array/ArrayList/LinkedList/List to bse namespace
// DONE: Remove the Input.h file and replace functionality with kevman
// TODO: Replace C style casts with C++ casts
// TODO: Add Move/Copy/Assignment stuff to vector, array etc (all where it's missing)
// Scheduler doesn't return
return 0;

View File

@ -17,7 +17,11 @@ private:
bse::vector<KeyEventListener*> listeners;
public:
KeyEventManager() : log("KEvMan") {}
KeyEventManager() : log("KEvMan"), listeners(true) {}
void init() {
listeners.reserve();
}
void subscribe(KeyEventListener& sub);
void unsubscribe(KeyEventListener& unsub);

View File

@ -26,9 +26,12 @@ namespace bse {
std::size_t buf_pos = 0;
std::size_t buf_cap = 0;
void init() {
buf = new T[vector::default_cap];
buf_cap = vector::default_cap;
void init(std::size_t cap = vector::default_cap) {
if (buf != nullptr) {
return;
}
buf = new T[cap];
buf_cap = cap;
}
std::size_t get_rem_cap() const {
@ -98,7 +101,12 @@ namespace bse {
}
public:
vector() = default;
vector(bool lazy = false) {
if (!lazy) { // I added this as a work around, the scheduler can't initialize the queues right
// away because when the scheduler is started the allocator is not ready.
init();
}
};
vector(const vector& copy) {
buf_cap = copy.buf_cap;
@ -147,6 +155,10 @@ namespace bse {
}
~vector() {
if (buf == nullptr) {
return;
}
for (std::size_t i; i < size(); ++i) {
buf[i].~T(); // TODO: I think delete[] buf calls these, verify that
}
@ -154,48 +166,20 @@ namespace bse {
}
// Iterator
iterator begin() {
if (buf == nullptr) {
init();
}
return iterator(&buf[0]);
}
iterator begin() const {
if (buf == nullptr) {
init();
}
return iterator(&buf[0]);
}
iterator end() {
if (buf == nullptr) {
init();
}
return iterator(&buf[size()]);
}
iterator end() const {
if (buf == nullptr) {
init();
}
return iterator(&buf[size()]);
}
iterator begin() { return iterator(&buf[0]); }
iterator begin() const { return iterator(&buf[0]); }
iterator end() { return iterator(&buf[size()]); }
iterator end() const { return iterator(&buf[size()]); }
// Add elements
// https://en.cppreference.com/w/cpp/container/vector/push_back
void push_back(const T& copy) {
if (buf == nullptr) {
init();
}
buf[size()] = copy;
++buf_pos;
min_expand();
}
void push_back(T&& move) {
if (buf == nullptr) {
init();
}
buf[size()] = std::move(move);
++buf_pos;
min_expand();
@ -273,12 +257,25 @@ namespace bse {
}
}
void reserve(std::size_t cap) {
void reserve(std::size_t cap = vector::default_cap) {
// The first reserve could allocate double if cap != default_cap
if (buf == nullptr) {
init();
// Directly init with correct size
init(cap);
return;
}
if (cap == buf_cap) {
// Would change nothing
return;
}
switch_buf(cap);
}
bool initialized() const {
return buf != nullptr;
}
};
// Erase all elements that match a predicate