simplify Qeue, update some comments and include paths
This commit is contained in:
committed by
Eggert Jung
parent
68e11c9793
commit
d9978ddc37
@@ -156,7 +156,7 @@ void set(uint32_t counter, uint8_t divide, uint8_t vector, bool periodic,
|
|||||||
*
|
*
|
||||||
* Initializes the \ref LAPIC::Timer
|
* Initializes the \ref LAPIC::Timer
|
||||||
* in such a way that regular interrupts are triggered approx. every `us`
|
* in such a way that regular interrupts are triggered approx. every `us`
|
||||||
* microseconds when \ref LAPIC::Timer:::activate() is called.
|
* microseconds when \ref LAPIC::Timer::activate() is called.
|
||||||
* For this purpose, a suitable timer divisor is determined
|
* For this purpose, a suitable timer divisor is determined
|
||||||
* based on the timer frequency determined with \ref LAPIC::Timer::ticks().
|
* based on the timer frequency determined with \ref LAPIC::Timer::ticks().
|
||||||
* This timer divisor has to be as small as possible, but large enough to
|
* This timer divisor has to be as small as possible, but large enough to
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "boot/multiboot/data.h"
|
#include "./data.h"
|
||||||
|
|
||||||
/*! \brief Multiboot Information Structure according to Specification
|
/*! \brief Multiboot Information Structure according to Specification
|
||||||
* \see [Multiboot Specification]{@ref multiboot}
|
* \see [Multiboot Specification]{@ref multiboot}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Epilogues {
|
|||||||
* \todo(15) Store the key to the keyboard buffer for user threads. Wake user
|
* \todo(15) Store the key to the keyboard buffer for user threads. Wake user
|
||||||
* threads waiting for a key using the key semaphore.
|
* threads waiting for a key using the key semaphore.
|
||||||
*
|
*
|
||||||
* @param g
|
* @param v The vault.
|
||||||
*/
|
*/
|
||||||
void keyboard(Vault& g);
|
void keyboard(Vault& g);
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ void keyboard(Vault& g);
|
|||||||
* \todo(15) Preemptively reschedule threads
|
* \todo(15) Preemptively reschedule threads
|
||||||
* \todo(16) Check the bellringer
|
* \todo(16) Check the bellringer
|
||||||
* \todo(17) Refresh screen with fixed FPS rate
|
* \todo(17) Refresh screen with fixed FPS rate
|
||||||
* @param g
|
* @param v The vault.
|
||||||
*/
|
*/
|
||||||
void timer(Vault& g);
|
void timer(Vault& g);
|
||||||
|
|
||||||
@@ -45,6 +45,7 @@ void timer(Vault& g);
|
|||||||
* it is set.
|
* it is set.
|
||||||
*
|
*
|
||||||
* \todo(15) Implement the rescheduling (in \MPStuBS only)
|
* \todo(15) Implement the rescheduling (in \MPStuBS only)
|
||||||
|
* @param v The vault.
|
||||||
*/
|
*/
|
||||||
void assassin(Vault& g);
|
void assassin(Vault& g);
|
||||||
}; // namespace Epilogues
|
}; // namespace Epilogues
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "handlers.h"
|
#include "./handlers.h"
|
||||||
|
|
||||||
#include "../arch/core_cr.h"
|
#include "../arch/core_cr.h"
|
||||||
#include "../arch/idt.h"
|
#include "../arch/idt.h"
|
||||||
@@ -29,8 +29,7 @@ void printContext(const InterruptContext *context) {
|
|||||||
|
|
||||||
[[gnu::interrupt]] void handle_double_fault(InterruptContext *context,
|
[[gnu::interrupt]] void handle_double_fault(InterruptContext *context,
|
||||||
uint64_t error) {
|
uint64_t error) {
|
||||||
(void)error;
|
DBG << "Double fault encountered. Error code: " << dec << error << endl;
|
||||||
DBG << "Double fault encoutered" << endl;
|
|
||||||
printContext(context);
|
printContext(context);
|
||||||
kernelpanic("Double fault!");
|
kernelpanic("Double fault!");
|
||||||
}
|
}
|
||||||
@@ -61,8 +60,12 @@ enum PAGE_FAULT_ERROR {
|
|||||||
|
|
||||||
[[gnu::interrupt]] void handle_page_fault(InterruptContext *context,
|
[[gnu::interrupt]] void handle_page_fault(InterruptContext *context,
|
||||||
uint64_t error) {
|
uint64_t error) {
|
||||||
|
<<<<<<< HEAD
|
||||||
(void)error;
|
(void)error;
|
||||||
DBG << "Page fault encoutered at linear address " << hex
|
DBG << "Page fault encoutered at linear address " << hex
|
||||||
|
=======
|
||||||
|
DBG << "Page fault encountered at linear address " << hex
|
||||||
|
>>>>>>> c0b78ee (simplify Qeue, update some comments and include paths)
|
||||||
<< Core::CR<2>::read() << endl
|
<< Core::CR<2>::read() << endl
|
||||||
<< (error & PF_ERR_PRESENT ? "present" : "non-present") << " page|"
|
<< (error & PF_ERR_PRESENT ? "present" : "non-present") << " page|"
|
||||||
<< (error & PF_ERR_WRITE ? "write" : "read") << " access|"
|
<< (error & PF_ERR_WRITE ? "write" : "read") << " access|"
|
||||||
|
|||||||
2
main.cc
2
main.cc
@@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
#include "arch/lapic.h"
|
#include "arch/lapic.h"
|
||||||
#include "boot/startup_ap.h"
|
#include "boot/startup_ap.h"
|
||||||
#include "arch/core_interrupt.h"
|
#include "arch/core_interrupt.h"
|
||||||
@@ -100,7 +101,6 @@ Application application = Application(test1_stack);
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Main function
|
// Main function
|
||||||
// (the bootstrap processor starts here)}
|
// (the bootstrap processor starts here)}
|
||||||
extern "C" int main() {
|
extern "C" int main() {
|
||||||
|
|||||||
@@ -11,39 +11,16 @@
|
|||||||
/*! \brief Templated Queue for arbitrary objects.
|
/*! \brief Templated Queue for arbitrary objects.
|
||||||
*
|
*
|
||||||
* Queue is implemented by a head-object (Queue<T>) and next-pointers embedded
|
* Queue is implemented by a head-object (Queue<T>) and next-pointers embedded
|
||||||
* in the queued objects. This Queue supports arrays of next-pointers by passing
|
* in the queued objects. By passing a different get_link function into the
|
||||||
* an index into the constructor identifying the index into the next-pointer
|
* constructor, the member name of the next-pointer can be changed and objects
|
||||||
* array. By passing a different get_link function into the constructor, the
|
* can be contained in different independent queues.
|
||||||
* member name of the next-pointer array can be changed and objects can be
|
|
||||||
* contained in different independent queues.
|
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
class Queue {
|
class Queue {
|
||||||
/*! \brief Default get_link implementation returns a pointer to the
|
/// Default get_link implementation returns a pointer to the next-pointer.
|
||||||
* link_index'th element of the next-pointer array.
|
static T** default_get_link(T& obj) { return &obj.queue_link; }
|
||||||
* The function assumes a member named "queue_link" that stores the
|
|
||||||
* next-pointer.
|
|
||||||
*
|
|
||||||
* If your object contains a queue_link member you can just ignore this
|
|
||||||
* function and the get_link keyword argument of the constructor.
|
|
||||||
*
|
|
||||||
* \param[in] obj the object whose link should be accessed.
|
|
||||||
* \param[in] link_index the index within the array.
|
|
||||||
*
|
|
||||||
* \return A pointer to the next-object pointer.
|
|
||||||
*/
|
|
||||||
static T** default_get_link(T& obj, unsigned link_index) {
|
|
||||||
assert(link_index < sizeof(T::queue_link) / sizeof(void*));
|
|
||||||
return &obj.queue_link[link_index];
|
|
||||||
}
|
|
||||||
/// Type definition for the get_link function
|
/// Type definition for the get_link function
|
||||||
typedef T** (*NextFunc)(T&, unsigned);
|
typedef T** (*NextFunc)(T&);
|
||||||
|
|
||||||
/// Queue-local index into the next-pointer array
|
|
||||||
unsigned link_index;
|
|
||||||
|
|
||||||
/// Provides the same signature for single- and multi-core Queue
|
|
||||||
T** get_link_wrapped(T& obj) { return get_link(obj, link_index); }
|
|
||||||
|
|
||||||
/// Function pointer to the get_link function, called whenever the
|
/// Function pointer to the get_link function, called whenever the
|
||||||
/// next pointer array is referenced
|
/// next pointer array is referenced
|
||||||
@@ -106,18 +83,15 @@ class Queue {
|
|||||||
constexpr Queue(Queue&&) = default;
|
constexpr Queue(Queue&&) = default;
|
||||||
|
|
||||||
/*! \brief Constructor
|
/*! \brief Constructor
|
||||||
* \param[in] link_index denotes the index into the next-pointer array
|
|
||||||
* to be used by this
|
|
||||||
*queue-object
|
|
||||||
* \param[in] get_link A function pointer to the get_link, i.e. a function
|
* \param[in] get_link A function pointer to the get_link, i.e. a function
|
||||||
* which returns a pointer to the
|
* which returns a pointer to the
|
||||||
*next-pointer of an element in the Queue.
|
*next-pointer of an element in the Queue.
|
||||||
*/
|
*/
|
||||||
explicit Queue(unsigned link_index, NextFunc get_link = default_get_link)
|
explicit Queue(NextFunc get_link = default_get_link)
|
||||||
: link_index(link_index),
|
: get_link(get_link), head(nullptr), tail(nullptr) {
|
||||||
get_link(get_link),
|
assert(get_link != nullptr &&
|
||||||
head(nullptr),
|
"get_link function pointer must not be nullptr!");
|
||||||
tail(nullptr) {}
|
};
|
||||||
|
|
||||||
/*! \brief Enqueues the provided item at the end of the queue. If the element
|
/*! \brief Enqueues the provided item at the end of the queue. If the element
|
||||||
* is already contained in the queue, false will be returned
|
* is already contained in the queue, false will be returned
|
||||||
@@ -126,7 +100,7 @@ class Queue {
|
|||||||
* or not (and it is now enqueued, then true)
|
* or not (and it is now enqueued, then true)
|
||||||
*/
|
*/
|
||||||
bool enqueue(T& item) {
|
bool enqueue(T& item) {
|
||||||
T** nextptr = get_link_wrapped(item);
|
T** nextptr = get_link(item);
|
||||||
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
|
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -136,7 +110,7 @@ class Queue {
|
|||||||
head = tail = &item;
|
head = tail = &item;
|
||||||
} else {
|
} else {
|
||||||
assert(tail != nullptr);
|
assert(tail != nullptr);
|
||||||
*get_link_wrapped(*tail) = &item;
|
*get_link(*tail) = &item;
|
||||||
tail = &item;
|
tail = &item;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -147,7 +121,7 @@ class Queue {
|
|||||||
* \return true if successful, false if item was already in the queue
|
* \return true if successful, false if item was already in the queue
|
||||||
**/
|
**/
|
||||||
bool insertFirst(T& item) {
|
bool insertFirst(T& item) {
|
||||||
T** nextptr = get_link_wrapped(item);
|
T** nextptr = get_link(item);
|
||||||
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
|
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -177,13 +151,13 @@ class Queue {
|
|||||||
if (&after == tail) {
|
if (&after == tail) {
|
||||||
return enqueue(item);
|
return enqueue(item);
|
||||||
}
|
}
|
||||||
T** nextptr = get_link_wrapped(item);
|
T** nextptr = get_link(item);
|
||||||
// if item is already in the list return false
|
// if item is already in the list return false
|
||||||
if (*nextptr != nullptr || tail == &item) {
|
if (*nextptr != nullptr || tail == &item) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
T** pnextptr = get_link_wrapped(after);
|
T** pnextptr = get_link(after);
|
||||||
// if after is NOT in the list, return false
|
// if after is NOT in the list, return false
|
||||||
if (!(pnextptr != nullptr || tail == &after)) {
|
if (!(pnextptr != nullptr || tail == &after)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -201,8 +175,7 @@ class Queue {
|
|||||||
*not in this list
|
*not in this list
|
||||||
**/
|
**/
|
||||||
T* next(T& item) {
|
T* next(T& item) {
|
||||||
T** nextptr = get_link_wrapped(item);
|
T** nextptr = get_link(item);
|
||||||
// if item is already in the list return nullptr
|
|
||||||
if (head == nullptr || (*nextptr == nullptr && tail != &item)) {
|
if (head == nullptr || (*nextptr == nullptr && tail != &item)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -222,7 +195,7 @@ class Queue {
|
|||||||
T* dequeue() {
|
T* dequeue() {
|
||||||
T* out = head;
|
T* out = head;
|
||||||
if (head != nullptr) {
|
if (head != nullptr) {
|
||||||
T** nextptr = get_link_wrapped(*head);
|
T** nextptr = get_link(*head);
|
||||||
head = *nextptr;
|
head = *nextptr;
|
||||||
*nextptr = nullptr;
|
*nextptr = nullptr;
|
||||||
}
|
}
|
||||||
@@ -239,21 +212,21 @@ class Queue {
|
|||||||
T** next_link;
|
T** next_link;
|
||||||
|
|
||||||
if (head == that) {
|
if (head == that) {
|
||||||
head = *get_link_wrapped(*head);
|
head = *get_link(*head);
|
||||||
|
|
||||||
*get_link_wrapped(*that) = nullptr;
|
*get_link(*that) = nullptr;
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
while (cur) {
|
while (cur) {
|
||||||
next_link = get_link_wrapped(*cur);
|
next_link = get_link(*cur);
|
||||||
if (*next_link == that) {
|
if (*next_link == that) {
|
||||||
*next_link = *get_link_wrapped(**next_link);
|
*next_link = *get_link(**next_link);
|
||||||
|
|
||||||
if (that == tail) {
|
if (that == tail) {
|
||||||
tail = cur;
|
tail = cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
*get_link_wrapped(*that) = nullptr;
|
*get_link(*that) = nullptr;
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
cur = *next_link;
|
cur = *next_link;
|
||||||
|
|||||||
@@ -1,19 +1,6 @@
|
|||||||
#include "bellringer.h"
|
#include "./bellringer.h"
|
||||||
|
|
||||||
#include "../interrupt/guard.h"
|
#include "../interrupt/guard.h"
|
||||||
#include "../thread/thread.h"
|
|
||||||
|
|
||||||
struct Bell {
|
|
||||||
// link pointer to the next bell in the bellringers bell list
|
|
||||||
Bell *queue_link[1] = {nullptr};
|
|
||||||
|
|
||||||
Thread *thread;
|
|
||||||
size_t counter;
|
|
||||||
};
|
|
||||||
|
|
||||||
Bell **Bellringer::bell_link(Bell &obj, unsigned link_index) {
|
|
||||||
return &obj.queue_link[link_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// check: Checks whether bells are running out of time and rings them if
|
// check: Checks whether bells are running out of time and rings them if
|
||||||
// necessary
|
// necessary
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../object/queue.h"
|
#include "../object/queue.h"
|
||||||
|
#include "../thread/thread.h"
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
|
||||||
struct Vault;
|
struct Vault;
|
||||||
struct Bell;
|
|
||||||
|
|
||||||
/*! \brief Manages and activates time-triggered activities.
|
/*! \brief Manages and activates time-triggered activities.
|
||||||
* \ingroup ipc
|
* \ingroup ipc
|
||||||
@@ -24,6 +24,14 @@ class Bellringer {
|
|||||||
Bellringer(const Bellringer&) = delete;
|
Bellringer(const Bellringer&) = delete;
|
||||||
Bellringer& operator=(const Bellringer&) = delete;
|
Bellringer& operator=(const Bellringer&) = delete;
|
||||||
|
|
||||||
|
struct Bell {
|
||||||
|
// link pointer to the next bell in the bellringers bell list
|
||||||
|
Bell* queue_link = nullptr;
|
||||||
|
|
||||||
|
Thread* thread;
|
||||||
|
size_t counter;
|
||||||
|
};
|
||||||
|
|
||||||
/*! \brief List of bells currently managed.
|
/*! \brief List of bells currently managed.
|
||||||
*
|
*
|
||||||
* This list contains non-expired bells enqueued by job().
|
* This list contains non-expired bells enqueued by job().
|
||||||
@@ -34,26 +42,26 @@ class Bellringer {
|
|||||||
*/
|
*/
|
||||||
Queue<Bell> bells;
|
Queue<Bell> bells;
|
||||||
|
|
||||||
//! Link pointer for bells
|
|
||||||
static Bell** bell_link(Bell& obj, unsigned link_index);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
Bellringer() : bells(0, bell_link) {}
|
Bellringer() : bells() {}
|
||||||
|
|
||||||
/*! \brief Checks whether there are bells to be rung.
|
/*! \brief Checks whether there are bells to be rung.
|
||||||
*
|
*
|
||||||
* Every call to check elapses a tick. Once such a tick reduces a bells
|
* Every call to check elapses a tick. Once such a tick reduces a bells
|
||||||
* remaining time to zero, the bell will be rung.
|
* remaining time to zero, the bell will be rung.
|
||||||
*
|
*
|
||||||
|
* \param vault The vault containing the bellringer instance
|
||||||
|
*
|
||||||
* \todo(16) Implement Method
|
* \todo(16) Implement Method
|
||||||
*/
|
*/
|
||||||
void check(Vault& vault);
|
void check(Vault& vault);
|
||||||
|
|
||||||
/*! \brief Passes a `bell` to the bellringer to be rung after `ms`
|
/*! \brief Passes a `bell` to the bellringer to be rung after `ms`
|
||||||
* milliseconds.
|
* milliseconds.
|
||||||
* \param bell Bell that should be rung after `ms` milliseconds
|
*
|
||||||
* \param ms number of milliseconds that should be waited before
|
* \param vault The vault containing the bellringer instance
|
||||||
|
* \param ms Number of milliseconds that should be waited before
|
||||||
* ringing the bell
|
* ringing the bell
|
||||||
*
|
*
|
||||||
* \todo(16) Implement Method
|
* \todo(16) Implement Method
|
||||||
|
|||||||
@@ -1,16 +1,7 @@
|
|||||||
#include "./semaphore.h"
|
#include "./semaphore.h"
|
||||||
|
|
||||||
#include "../interrupt/guard.h"
|
|
||||||
#include "../thread/thread.h"
|
|
||||||
|
|
||||||
Semaphore::Semaphore(unsigned c) { (void)c; }
|
Semaphore::Semaphore(unsigned c) { (void)c; }
|
||||||
|
|
||||||
Thread **Semaphore::thread_link(Thread &obj, unsigned link_index) {
|
|
||||||
(void)obj;
|
|
||||||
(void)link_index;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Semaphore::p(Vault &vault) { (void)vault; }
|
void Semaphore::p(Vault &vault) { (void)vault; }
|
||||||
|
|
||||||
void Semaphore::v(Vault &vault) { (void)vault; }
|
void Semaphore::v(Vault &vault) { (void)vault; }
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ class Semaphore {
|
|||||||
Semaphore(const Semaphore&) = delete;
|
Semaphore(const Semaphore&) = delete;
|
||||||
Semaphore& operator=(const Semaphore&) = delete;
|
Semaphore& operator=(const Semaphore&) = delete;
|
||||||
|
|
||||||
static Thread** thread_link(Thread& obj, unsigned link_index);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! \brief Constructor; initialized the counter with provided value `c`
|
/*! \brief Constructor; initialized the counter with provided value `c`
|
||||||
* \param c Initial counter value
|
* \param c Initial counter value
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "../types.h"
|
||||||
|
|
||||||
#include "../arch/core.h"
|
#include "../arch/core.h"
|
||||||
#include "../arch/cache.h"
|
#include "../arch/cache.h"
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ void Scheduler::kill(Thread* that) {
|
|||||||
that->kill_flag = true;
|
that->kill_flag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scheduler::isActive(const Thread* that, unsigned int* cpu) {
|
bool Scheduler::isActive(const Thread* thread, unsigned int* cpu) {
|
||||||
(void)that;
|
(void)thread;
|
||||||
(void)cpu;
|
(void)cpu;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ class Scheduler {
|
|||||||
Thread* active() { return dispatcher.active(); }
|
Thread* active() { return dispatcher.active(); }
|
||||||
|
|
||||||
/// \copydoc Dispatcher::isActive
|
/// \copydoc Dispatcher::isActive
|
||||||
bool isActive(const Thread* that, unsigned int* cpu = nullptr);
|
bool isActive(const Thread* thread, unsigned int* cpu = nullptr);
|
||||||
|
|
||||||
/*! \brief Checks whether the ready queue is empty.
|
/*! \brief Checks whether the ready queue is empty.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user