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
|
||||
* 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
|
||||
* 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "boot/multiboot/data.h"
|
||||
#include "./data.h"
|
||||
|
||||
/*! \brief Multiboot Information Structure according to Specification
|
||||
* \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
|
||||
* threads waiting for a key using the key semaphore.
|
||||
*
|
||||
* @param g
|
||||
* @param v The vault.
|
||||
*/
|
||||
void keyboard(Vault& g);
|
||||
|
||||
@@ -37,7 +37,7 @@ void keyboard(Vault& g);
|
||||
* \todo(15) Preemptively reschedule threads
|
||||
* \todo(16) Check the bellringer
|
||||
* \todo(17) Refresh screen with fixed FPS rate
|
||||
* @param g
|
||||
* @param v The vault.
|
||||
*/
|
||||
void timer(Vault& g);
|
||||
|
||||
@@ -45,6 +45,7 @@ void timer(Vault& g);
|
||||
* it is set.
|
||||
*
|
||||
* \todo(15) Implement the rescheduling (in \MPStuBS only)
|
||||
* @param v The vault.
|
||||
*/
|
||||
void assassin(Vault& g);
|
||||
}; // namespace Epilogues
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "handlers.h"
|
||||
#include "./handlers.h"
|
||||
|
||||
#include "../arch/core_cr.h"
|
||||
#include "../arch/idt.h"
|
||||
@@ -29,8 +29,7 @@ void printContext(const InterruptContext *context) {
|
||||
|
||||
[[gnu::interrupt]] void handle_double_fault(InterruptContext *context,
|
||||
uint64_t error) {
|
||||
(void)error;
|
||||
DBG << "Double fault encoutered" << endl;
|
||||
DBG << "Double fault encountered. Error code: " << dec << error << endl;
|
||||
printContext(context);
|
||||
kernelpanic("Double fault!");
|
||||
}
|
||||
@@ -61,8 +60,12 @@ enum PAGE_FAULT_ERROR {
|
||||
|
||||
[[gnu::interrupt]] void handle_page_fault(InterruptContext *context,
|
||||
uint64_t error) {
|
||||
<<<<<<< HEAD
|
||||
(void)error;
|
||||
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
|
||||
<< (error & PF_ERR_PRESENT ? "present" : "non-present") << " page|"
|
||||
<< (error & PF_ERR_WRITE ? "write" : "read") << " access|"
|
||||
|
||||
2
main.cc
2
main.cc
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
#include "arch/lapic.h"
|
||||
#include "boot/startup_ap.h"
|
||||
#include "arch/core_interrupt.h"
|
||||
@@ -100,7 +101,6 @@ Application application = Application(test1_stack);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
// Main function
|
||||
// (the bootstrap processor starts here)}
|
||||
extern "C" int main() {
|
||||
|
||||
@@ -11,39 +11,16 @@
|
||||
/*! \brief Templated Queue for arbitrary objects.
|
||||
*
|
||||
* 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
|
||||
* an index into the constructor identifying the index into the next-pointer
|
||||
* array. By passing a different get_link function into the constructor, the
|
||||
* member name of the next-pointer array can be changed and objects can be
|
||||
* contained in different independent queues.
|
||||
* in the queued objects. By passing a different get_link function into the
|
||||
* constructor, the member name of the next-pointer can be changed and objects
|
||||
* can be contained in different independent queues.
|
||||
*/
|
||||
template <class T>
|
||||
class Queue {
|
||||
/*! \brief Default get_link implementation returns a pointer to the
|
||||
* link_index'th element of the next-pointer array.
|
||||
* 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];
|
||||
}
|
||||
/// Default get_link implementation returns a pointer to the next-pointer.
|
||||
static T** default_get_link(T& obj) { return &obj.queue_link; }
|
||||
/// Type definition for the get_link function
|
||||
typedef T** (*NextFunc)(T&, unsigned);
|
||||
|
||||
/// 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); }
|
||||
typedef T** (*NextFunc)(T&);
|
||||
|
||||
/// Function pointer to the get_link function, called whenever the
|
||||
/// next pointer array is referenced
|
||||
@@ -106,18 +83,15 @@ class Queue {
|
||||
constexpr Queue(Queue&&) = default;
|
||||
|
||||
/*! \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
|
||||
* which returns a pointer to the
|
||||
*next-pointer of an element in the Queue.
|
||||
*/
|
||||
explicit Queue(unsigned link_index, NextFunc get_link = default_get_link)
|
||||
: link_index(link_index),
|
||||
get_link(get_link),
|
||||
head(nullptr),
|
||||
tail(nullptr) {}
|
||||
explicit Queue(NextFunc get_link = default_get_link)
|
||||
: get_link(get_link), head(nullptr), tail(nullptr) {
|
||||
assert(get_link != nullptr &&
|
||||
"get_link function pointer must not be nullptr!");
|
||||
};
|
||||
|
||||
/*! \brief Enqueues the provided item at the end of the queue. If the element
|
||||
* 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)
|
||||
*/
|
||||
bool enqueue(T& item) {
|
||||
T** nextptr = get_link_wrapped(item);
|
||||
T** nextptr = get_link(item);
|
||||
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
|
||||
return false;
|
||||
}
|
||||
@@ -136,7 +110,7 @@ class Queue {
|
||||
head = tail = &item;
|
||||
} else {
|
||||
assert(tail != nullptr);
|
||||
*get_link_wrapped(*tail) = &item;
|
||||
*get_link(*tail) = &item;
|
||||
tail = &item;
|
||||
}
|
||||
return true;
|
||||
@@ -147,7 +121,7 @@ class Queue {
|
||||
* \return true if successful, false if item was already in the queue
|
||||
**/
|
||||
bool insertFirst(T& item) {
|
||||
T** nextptr = get_link_wrapped(item);
|
||||
T** nextptr = get_link(item);
|
||||
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
|
||||
return false;
|
||||
}
|
||||
@@ -177,13 +151,13 @@ class Queue {
|
||||
if (&after == tail) {
|
||||
return enqueue(item);
|
||||
}
|
||||
T** nextptr = get_link_wrapped(item);
|
||||
T** nextptr = get_link(item);
|
||||
// if item is already in the list return false
|
||||
if (*nextptr != nullptr || tail == &item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
T** pnextptr = get_link_wrapped(after);
|
||||
T** pnextptr = get_link(after);
|
||||
// if after is NOT in the list, return false
|
||||
if (!(pnextptr != nullptr || tail == &after)) {
|
||||
return false;
|
||||
@@ -201,8 +175,7 @@ class Queue {
|
||||
*not in this list
|
||||
**/
|
||||
T* next(T& item) {
|
||||
T** nextptr = get_link_wrapped(item);
|
||||
// if item is already in the list return nullptr
|
||||
T** nextptr = get_link(item);
|
||||
if (head == nullptr || (*nextptr == nullptr && tail != &item)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -222,7 +195,7 @@ class Queue {
|
||||
T* dequeue() {
|
||||
T* out = head;
|
||||
if (head != nullptr) {
|
||||
T** nextptr = get_link_wrapped(*head);
|
||||
T** nextptr = get_link(*head);
|
||||
head = *nextptr;
|
||||
*nextptr = nullptr;
|
||||
}
|
||||
@@ -239,21 +212,21 @@ class Queue {
|
||||
T** next_link;
|
||||
|
||||
if (head == that) {
|
||||
head = *get_link_wrapped(*head);
|
||||
head = *get_link(*head);
|
||||
|
||||
*get_link_wrapped(*that) = nullptr;
|
||||
*get_link(*that) = nullptr;
|
||||
return that;
|
||||
}
|
||||
while (cur) {
|
||||
next_link = get_link_wrapped(*cur);
|
||||
next_link = get_link(*cur);
|
||||
if (*next_link == that) {
|
||||
*next_link = *get_link_wrapped(**next_link);
|
||||
*next_link = *get_link(**next_link);
|
||||
|
||||
if (that == tail) {
|
||||
tail = cur;
|
||||
}
|
||||
|
||||
*get_link_wrapped(*that) = nullptr;
|
||||
*get_link(*that) = nullptr;
|
||||
return that;
|
||||
}
|
||||
cur = *next_link;
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
#include "bellringer.h"
|
||||
#include "./bellringer.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
|
||||
// necessary
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
#include "../object/queue.h"
|
||||
#include "../thread/thread.h"
|
||||
#include "../types.h"
|
||||
|
||||
struct Vault;
|
||||
struct Bell;
|
||||
|
||||
/*! \brief Manages and activates time-triggered activities.
|
||||
* \ingroup ipc
|
||||
@@ -24,6 +24,14 @@ class Bellringer {
|
||||
Bellringer(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.
|
||||
*
|
||||
* This list contains non-expired bells enqueued by job().
|
||||
@@ -34,26 +42,26 @@ class Bellringer {
|
||||
*/
|
||||
Queue<Bell> bells;
|
||||
|
||||
//! Link pointer for bells
|
||||
static Bell** bell_link(Bell& obj, unsigned link_index);
|
||||
|
||||
public:
|
||||
// constructor
|
||||
Bellringer() : bells(0, bell_link) {}
|
||||
Bellringer() : bells() {}
|
||||
|
||||
/*! \brief Checks whether there are bells to be rung.
|
||||
*
|
||||
* Every call to check elapses a tick. Once such a tick reduces a bells
|
||||
* remaining time to zero, the bell will be rung.
|
||||
*
|
||||
* \param vault The vault containing the bellringer instance
|
||||
*
|
||||
* \todo(16) Implement Method
|
||||
*/
|
||||
void check(Vault& vault);
|
||||
|
||||
/*! \brief Passes a `bell` to the bellringer to be rung after `ms`
|
||||
* 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
|
||||
*
|
||||
* \todo(16) Implement Method
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
#include "./semaphore.h"
|
||||
|
||||
#include "../interrupt/guard.h"
|
||||
#include "../thread/thread.h"
|
||||
|
||||
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::v(Vault &vault) { (void)vault; }
|
||||
|
||||
@@ -26,8 +26,6 @@ class Semaphore {
|
||||
Semaphore(const Semaphore&) = delete;
|
||||
Semaphore& operator=(const Semaphore&) = delete;
|
||||
|
||||
static Thread** thread_link(Thread& obj, unsigned link_index);
|
||||
|
||||
public:
|
||||
/*! \brief Constructor; initialized the counter with provided value `c`
|
||||
* \param c Initial counter value
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
|
||||
#include "../arch/core.h"
|
||||
#include "../arch/cache.h"
|
||||
|
||||
@@ -41,8 +41,8 @@ void Scheduler::kill(Thread* that) {
|
||||
that->kill_flag = true;
|
||||
}
|
||||
|
||||
bool Scheduler::isActive(const Thread* that, unsigned int* cpu) {
|
||||
(void)that;
|
||||
bool Scheduler::isActive(const Thread* thread, unsigned int* cpu) {
|
||||
(void)thread;
|
||||
(void)cpu;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class Scheduler {
|
||||
Thread* active() { return dispatcher.active(); }
|
||||
|
||||
/// \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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user