allow vector to be lazy init if alloc not avail
This commit is contained in:
@ -45,7 +45,13 @@ private:
|
|||||||
void ready(bse::unique_ptr<Thread>&& thread);
|
void ready(bse::unique_ptr<Thread>&& thread);
|
||||||
|
|
||||||
public:
|
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 {
|
unsigned int get_active() const {
|
||||||
return (*active)->tid;
|
return (*active)->tid;
|
||||||
|
|||||||
@ -11,6 +11,9 @@ void Semaphore::p() {
|
|||||||
this->lock.release();
|
this->lock.release();
|
||||||
} else {
|
} else {
|
||||||
// Block and manage thread in semaphore queue until it's woken up by v() again
|
// 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());
|
this->wait_queue.push_back(scheduler.get_active());
|
||||||
|
|
||||||
CPU::disable_int(); // Make sure the block() comes through after releasing the lock
|
CPU::disable_int(); // Make sure the block() comes through after releasing the lock
|
||||||
|
|||||||
@ -27,7 +27,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Konstruktor: Initialisieren des Semaphorzaehlers
|
// 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.
|
// 'Passieren': Warten auf das Freiwerden eines kritischen Abschnitts.
|
||||||
void p();
|
void p();
|
||||||
|
|||||||
@ -46,6 +46,8 @@ int main() {
|
|||||||
|
|
||||||
// Speicherverwaltung initialisieren
|
// Speicherverwaltung initialisieren
|
||||||
allocator.init();
|
allocator.init();
|
||||||
|
scheduler.init();
|
||||||
|
kevman.init();
|
||||||
|
|
||||||
// Tastatur-Unterbrechungsroutine 'einstoepseln'
|
// Tastatur-Unterbrechungsroutine 'einstoepseln'
|
||||||
kb.plugin();
|
kb.plugin();
|
||||||
@ -124,6 +126,7 @@ int main() {
|
|||||||
// DONE: Move Array/ArrayList/LinkedList/List to bse namespace
|
// DONE: Move Array/ArrayList/LinkedList/List to bse namespace
|
||||||
// DONE: Remove the Input.h file and replace functionality with kevman
|
// DONE: Remove the Input.h file and replace functionality with kevman
|
||||||
// TODO: Replace C style casts with C++ casts
|
// 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
|
// Scheduler doesn't return
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -17,7 +17,11 @@ private:
|
|||||||
bse::vector<KeyEventListener*> listeners;
|
bse::vector<KeyEventListener*> listeners;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KeyEventManager() : log("KEvMan") {}
|
KeyEventManager() : log("KEvMan"), listeners(true) {}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
listeners.reserve();
|
||||||
|
}
|
||||||
|
|
||||||
void subscribe(KeyEventListener& sub);
|
void subscribe(KeyEventListener& sub);
|
||||||
void unsubscribe(KeyEventListener& unsub);
|
void unsubscribe(KeyEventListener& unsub);
|
||||||
|
|||||||
@ -26,9 +26,12 @@ namespace bse {
|
|||||||
std::size_t buf_pos = 0;
|
std::size_t buf_pos = 0;
|
||||||
std::size_t buf_cap = 0;
|
std::size_t buf_cap = 0;
|
||||||
|
|
||||||
void init() {
|
void init(std::size_t cap = vector::default_cap) {
|
||||||
buf = new T[vector::default_cap];
|
if (buf != nullptr) {
|
||||||
buf_cap = vector::default_cap;
|
return;
|
||||||
|
}
|
||||||
|
buf = new T[cap];
|
||||||
|
buf_cap = cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t get_rem_cap() const {
|
std::size_t get_rem_cap() const {
|
||||||
@ -98,7 +101,12 @@ namespace bse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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) {
|
vector(const vector& copy) {
|
||||||
buf_cap = copy.buf_cap;
|
buf_cap = copy.buf_cap;
|
||||||
@ -147,6 +155,10 @@ namespace bse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~vector() {
|
~vector() {
|
||||||
|
if (buf == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (std::size_t i; i < size(); ++i) {
|
for (std::size_t i; i < size(); ++i) {
|
||||||
buf[i].~T(); // TODO: I think delete[] buf calls these, verify that
|
buf[i].~T(); // TODO: I think delete[] buf calls these, verify that
|
||||||
}
|
}
|
||||||
@ -154,48 +166,20 @@ namespace bse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Iterator
|
// Iterator
|
||||||
iterator begin() {
|
iterator begin() { return iterator(&buf[0]); }
|
||||||
if (buf == nullptr) {
|
iterator begin() const { return iterator(&buf[0]); }
|
||||||
init();
|
iterator end() { return iterator(&buf[size()]); }
|
||||||
}
|
iterator end() const { return iterator(&buf[size()]); }
|
||||||
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()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add elements
|
// Add elements
|
||||||
// https://en.cppreference.com/w/cpp/container/vector/push_back
|
// https://en.cppreference.com/w/cpp/container/vector/push_back
|
||||||
void push_back(const T& copy) {
|
void push_back(const T& copy) {
|
||||||
if (buf == nullptr) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[size()] = copy;
|
buf[size()] = copy;
|
||||||
++buf_pos;
|
++buf_pos;
|
||||||
min_expand();
|
min_expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_back(T&& move) {
|
void push_back(T&& move) {
|
||||||
if (buf == nullptr) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[size()] = std::move(move);
|
buf[size()] = std::move(move);
|
||||||
++buf_pos;
|
++buf_pos;
|
||||||
min_expand();
|
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) {
|
if (buf == nullptr) {
|
||||||
init();
|
// Directly init with correct size
|
||||||
|
init(cap);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cap == buf_cap) {
|
||||||
|
// Would change nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch_buf(cap);
|
switch_buf(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool initialized() const {
|
||||||
|
return buf != nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Erase all elements that match a predicate
|
// Erase all elements that match a predicate
|
||||||
|
|||||||
Reference in New Issue
Block a user