merged cleanup
This commit is contained in:
@ -19,8 +19,8 @@
|
||||
* Autor: Olaf Spinczyk, TU Dortmund *
|
||||
* Aenderungen von Michael Schoettner, HHU, 06.04.20 *
|
||||
*****************************************************************************/
|
||||
#ifndef __OutStream_include__
|
||||
#define __OutStream_include__
|
||||
#ifndef OutStream_include__
|
||||
#define OutStream_include__
|
||||
|
||||
#include "lib/StringBuffer.h"
|
||||
#include "user/lib/String.h"
|
||||
@ -40,8 +40,6 @@ public:
|
||||
|
||||
class OutStream : public StringBuffer {
|
||||
private:
|
||||
OutStream(const OutStream& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
// Some stream formatting
|
||||
unsigned char fill_used; // indicates how many characters are already used by the text internally
|
||||
unsigned char fill_width; // If input is shorter than fill_width fill remaining space up with fill_char
|
||||
@ -52,8 +50,12 @@ private:
|
||||
void fill_finalize(); // does the filling after text has been written to buffer
|
||||
|
||||
public:
|
||||
OutStream(const OutStream& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
OutStream() : fill_used(0), fill_width(0), fill_char(' '), base(10) {}
|
||||
|
||||
// ~OutStream() override = default;
|
||||
|
||||
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
|
||||
void flush() override;
|
||||
|
||||
@ -79,7 +81,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned char c) { return os << (char)c; }
|
||||
friend T& operator<<(T& os, unsigned char c) { return os << static_cast<char>(c); }
|
||||
|
||||
// Darstellung einer nullterminierten Zeichenkette
|
||||
template<typename T>
|
||||
@ -97,22 +99,22 @@ public:
|
||||
// Can not use this exclusively for strings as these are heap allocated
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, const bse::string& string) {
|
||||
os << (const char*)string;
|
||||
os << static_cast<const char*>(string);
|
||||
return os;
|
||||
}
|
||||
|
||||
// Darstellung ganzer Zahlen im Zahlensystem zur Basis base
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, short ival) { return os << (long)ival; }
|
||||
friend T& operator<<(T& os, short ival) { return os << static_cast<long>(ival); }
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned short ival) { return os << (unsigned long)ival; }
|
||||
friend T& operator<<(T& os, unsigned short ival) { return os << static_cast<unsigned long>(ival); }
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, int ival) { return os << (long)ival; }
|
||||
friend T& operator<<(T& os, int ival) { return os << static_cast<long>(ival); }
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned int ival) { return os << (unsigned long)ival; }
|
||||
friend T& operator<<(T& os, unsigned int ival) { return os << static_cast<unsigned long>(ival); }
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, long ival) {
|
||||
@ -122,13 +124,13 @@ public:
|
||||
ival = -ival;
|
||||
}
|
||||
// Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben.
|
||||
return os << (unsigned long)ival;
|
||||
return os << static_cast<unsigned long>(ival);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned long ival) {
|
||||
unsigned long div = 0;
|
||||
char digit = 0;
|
||||
unsigned long div;
|
||||
char digit;
|
||||
|
||||
if (os.base == 8) {
|
||||
os.put('0'); // oktale Zahlen erhalten eine fuehrende Null
|
||||
@ -139,10 +141,10 @@ public:
|
||||
|
||||
// Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die
|
||||
// noch kleiner als die darzustellende Zahl ist.
|
||||
for (div = 1; ival / div >= (unsigned long)os.base; div *= os.base) {}
|
||||
for (div = 1; ival / div >= static_cast<unsigned long>(os.base); div *= os.base) {}
|
||||
|
||||
// ziffernweise Ausgabe der Zahl
|
||||
for (; div > 0; div /= (unsigned long)os.base) {
|
||||
for (; div > 0; div /= static_cast<unsigned long>(os.base)) {
|
||||
digit = ival / div;
|
||||
if (digit < 10) {
|
||||
os.put('0' + digit);
|
||||
@ -160,7 +162,7 @@ public:
|
||||
friend T& operator<<(T& os, void* ptr) {
|
||||
int oldbase = os.base;
|
||||
os.base = 16;
|
||||
os << (unsigned long)ptr;
|
||||
os << reinterpret_cast<unsigned long>(ptr);
|
||||
os.base = oldbase;
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -3,39 +3,39 @@
|
||||
|
||||
void Semaphore::p() {
|
||||
// Lock to allow deterministic operations on counter/queue
|
||||
this->lock.acquire();
|
||||
lock.acquire();
|
||||
|
||||
if (this->counter > 0) {
|
||||
if (counter > 0) {
|
||||
// Semaphore can be acquired
|
||||
this->counter = this->counter - 1;
|
||||
this->lock.release();
|
||||
counter = counter - 1;
|
||||
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());
|
||||
wait_queue.push_back(scheduler.get_active());
|
||||
|
||||
CPU::disable_int(); // Make sure the block() comes through after releasing the lock
|
||||
this->lock.release();
|
||||
lock.release();
|
||||
scheduler.block(); // Moves to next thread, enables int
|
||||
}
|
||||
}
|
||||
|
||||
void Semaphore::v() {
|
||||
this->lock.acquire();
|
||||
lock.acquire();
|
||||
|
||||
if (!this->wait_queue.empty()) {
|
||||
if (!wait_queue.empty()) {
|
||||
// Semaphore stays busy and unblocks next thread to work in critical section
|
||||
unsigned int tid = this->wait_queue.front();
|
||||
this->wait_queue.erase(wait_queue.begin());
|
||||
unsigned int tid = wait_queue.front();
|
||||
wait_queue.erase(wait_queue.begin());
|
||||
|
||||
CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock
|
||||
this->lock.release();
|
||||
lock.release();
|
||||
scheduler.deblock(tid); // Enables int
|
||||
} else {
|
||||
// No more threads want to work so free semaphore
|
||||
this->counter = this->counter + 1;
|
||||
this->lock.release();
|
||||
counter = counter + 1;
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
* Autor: Michael Schoettner, 2.9.2016 *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __Semaphore_include__
|
||||
#define __Semaphore_include__
|
||||
#ifndef Semaphore_include__
|
||||
#define Semaphore_include__
|
||||
|
||||
#include "kernel/threads/Thread.h"
|
||||
#include "lib/SpinLock.h"
|
||||
@ -17,8 +17,6 @@
|
||||
|
||||
class Semaphore {
|
||||
private:
|
||||
Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
// Queue fuer wartende Threads.
|
||||
bse::vector<unsigned int> wait_queue;
|
||||
SpinLock lock;
|
||||
@ -26,6 +24,8 @@ private:
|
||||
int counter;
|
||||
|
||||
public:
|
||||
Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
// Konstruktor: Initialisieren des Semaphorzaehlers
|
||||
Semaphore(int c) : wait_queue(true), counter(c) {}
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "lib/SpinLock.h"
|
||||
#include "kernel/Globals.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: CAS *
|
||||
@ -24,7 +23,7 @@
|
||||
* *ptr := _new *
|
||||
* return prev *
|
||||
*****************************************************************************/
|
||||
static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned long _new) {
|
||||
static inline unsigned long CAS(const unsigned long* ptr) {
|
||||
unsigned long prev;
|
||||
|
||||
/*
|
||||
@ -38,7 +37,7 @@ static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned
|
||||
"cmpxchg %1, %2;" // %1 = _new; %2 = *ptr
|
||||
// constraints
|
||||
: "=a"(prev) // output: =a: RAX -> prev (%0))
|
||||
: "r"(_new), "m"(*ptr), "a"(old) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax
|
||||
: "r"(1), "m"(*ptr), "a"(0) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax
|
||||
: "memory"); // ensures assembly block will not be moved by gcc
|
||||
|
||||
return prev; // return pointer instead of prev to prevent unnecessary second call
|
||||
@ -52,7 +51,7 @@ static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned
|
||||
void SpinLock::acquire() {
|
||||
// If lock == 0 the SpinLock can be aquired without waiting
|
||||
// If lock == 1 the while loop blocks until aquired
|
||||
while (CAS(ptr, 0, 1) != 0) {}
|
||||
while (CAS(ptr) != 0) {}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
@ -9,17 +9,17 @@
|
||||
* Autor: Michael Schoettner, 2.2.2018 *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __SpinLock_include__
|
||||
#define __SpinLock_include__
|
||||
#ifndef SpinLock_include__
|
||||
#define SpinLock_include__
|
||||
|
||||
class SpinLock {
|
||||
private:
|
||||
SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
unsigned long lock;
|
||||
unsigned long* ptr;
|
||||
|
||||
public:
|
||||
SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
SpinLock() : lock(0), ptr(&lock) {}
|
||||
|
||||
void acquire();
|
||||
|
||||
@ -15,15 +15,12 @@
|
||||
* Autor: Olaf Spinczyk, TU Dortmund *
|
||||
* Aenderungen von Michael Schoettner, HHU, 06.04.20 *
|
||||
*****************************************************************************/
|
||||
#ifndef __StringBuffer_include__
|
||||
#define __StringBuffer_include__
|
||||
#ifndef StringBuffer_include__
|
||||
#define StringBuffer_include__
|
||||
|
||||
#include "user/lib/Array.h"
|
||||
|
||||
class StringBuffer {
|
||||
private:
|
||||
StringBuffer(const StringBuffer& copy); // Verhindere Kopieren
|
||||
|
||||
// Alle Variablen und Methoden dieser Klasse sind "protected",
|
||||
// da die abgeleiteten Klassen einen direkten Zugriff auf den
|
||||
// Puffer, den Konstruktor, den Destruktor und die Methode put
|
||||
@ -42,6 +39,10 @@ protected:
|
||||
|
||||
// Methode zur Ausgabe des Pufferinhalts
|
||||
virtual void flush() = 0;
|
||||
public:
|
||||
StringBuffer(const StringBuffer& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
// virtual ~StringBuffer() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user