penis
parent
b1892a7e82
commit
07f4f66ba5
1
Makefile
1
Makefile
|
@ -43,6 +43,7 @@ obj/src/%.o : src/%.c
|
||||||
|
|
||||||
obj/src/%.xo : src/%.cpp
|
obj/src/%.xo : src/%.cpp
|
||||||
@echo "[i] Compiling $*.cpp ..."
|
@echo "[i] Compiling $*.cpp ..."
|
||||||
|
@if [ -e obj/src/$*.xo ] ; then rm obj/src/$*.xo ; fi
|
||||||
@mkdir -p obj/src/$*.xo
|
@mkdir -p obj/src/$*.xo
|
||||||
@rmdir obj/src/$*.xo
|
@rmdir obj/src/$*.xo
|
||||||
@$(CX) $(CXFLAGS) -c src/$*.cpp -o obj/src/$*.xo
|
@$(CX) $(CXFLAGS) -c src/$*.cpp -o obj/src/$*.xo
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __CROUNDROBINSCHEDULER_H__
|
||||||
|
#define __CROUNDROBINSCHEDULER_H__
|
||||||
|
|
||||||
|
#include "Tier1/IScheduler.h"
|
||||||
|
#include "Tier1/Util/CLinearList.h"
|
||||||
|
|
||||||
|
namespace cb {
|
||||||
|
class CRoundRobinScheduler : public IScheduler {
|
||||||
|
public:
|
||||||
|
void Enable(bool Enabled);
|
||||||
|
void AddTask(CTask *Task);
|
||||||
|
void NextTask(void);
|
||||||
|
CTask *GetCurrentTask(void);
|
||||||
|
private:
|
||||||
|
CTask *m_CurrentTask;
|
||||||
|
CLinearList<CTask *> m_TaskQueue;
|
||||||
|
u32 m_TaskQueuePosition;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,6 +4,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include "Tier1/CTask.h"
|
#include "Tier1/CTask.h"
|
||||||
|
#include "Tier1/IScheduler.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "Tier0/interrupts.h"
|
#include "Tier0/interrupts.h"
|
||||||
|
@ -16,17 +17,13 @@ namespace cb {
|
||||||
} TTaskQueueNode;
|
} TTaskQueueNode;
|
||||||
class CScheduler {
|
class CScheduler {
|
||||||
private:
|
private:
|
||||||
CTask *m_CurrentTask;
|
IScheduler *m_CurrentScheduler;
|
||||||
|
|
||||||
TTaskQueueNode *m_TaskQueueStart;
|
|
||||||
TTaskQueueNode *m_TaskQueueCurrent;
|
|
||||||
|
|
||||||
static void TimerTick(T_ISR_REGISTERS R);
|
static void TimerTick(T_ISR_REGISTERS R);
|
||||||
public:
|
public:
|
||||||
CScheduler(void);
|
CScheduler(void);
|
||||||
static void Enable(void);
|
static void Enable(void);
|
||||||
static void AddTask(CTask *Task);
|
static void AddTask(CTask *Task);
|
||||||
static void NextTask(void);
|
|
||||||
static CTask *GetCurrentTask(void);
|
static CTask *GetCurrentTask(void);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,7 +129,25 @@ namespace cb {
|
||||||
// Equivalent of the POSIX fork() call.
|
// Equivalent of the POSIX fork() call.
|
||||||
CTask *Fork(void);
|
CTask *Fork(void);
|
||||||
|
|
||||||
u32 GetPID(void);
|
inline u32 GetPID(void) { return m_PID; }
|
||||||
|
inline u32 GetESP(void) { return m_ESP; }
|
||||||
|
inline u32 GetEIP(void) { return m_EIP; }
|
||||||
|
inline u32 GetEBP(void) { return m_EBP; }
|
||||||
|
|
||||||
|
inline u32 GetPageDirectoryPhysicalAddress(void)
|
||||||
|
{
|
||||||
|
//return m_Directory->m_Directory->PhysicalAddress;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetESP(u32 ESP) { m_ESP = ESP; }
|
||||||
|
inline void SetEIP(u32 EIP) { m_EIP = EIP; }
|
||||||
|
inline void SetEBP(u32 EBP) { m_EBP = EBP; }
|
||||||
|
|
||||||
|
inline void SetPageDirectory(CPageDirectory *Directory)
|
||||||
|
{
|
||||||
|
m_Directory = Directory;
|
||||||
|
}
|
||||||
|
|
||||||
void Dump(void);
|
void Dump(void);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __ISCHEDULER_H__
|
||||||
|
#define __ISCHEDULER_H__
|
||||||
|
|
||||||
|
#include "Tier1/CTask.h"
|
||||||
|
|
||||||
|
namespace cb {
|
||||||
|
class IScheduler {
|
||||||
|
public:
|
||||||
|
virtual void Enable(bool Enabled) = 0;
|
||||||
|
virtual void AddTask(CTask *Task) = 0;
|
||||||
|
virtual void NextTask(void) = 0;
|
||||||
|
virtual CTask *GetCurrentTask(void) = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,225 @@
|
||||||
|
#ifndef __CLINEAR_LIST_H__
|
||||||
|
#define __CLINEAR_LIST_H__
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "Tier0/heap.h"
|
||||||
|
#include "Tier0/panic.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace cb {
|
||||||
|
template <class _T> class CLinearList {
|
||||||
|
public:
|
||||||
|
CLinearList(void);
|
||||||
|
|
||||||
|
// Stack-like access
|
||||||
|
void Push(const _T &Element);
|
||||||
|
_T &Pop(void);
|
||||||
|
|
||||||
|
// Indexing operator
|
||||||
|
_T &operator[](u32 Index);
|
||||||
|
const _T &operator[](u32 Index) const;
|
||||||
|
|
||||||
|
void Insert(const _T &Element, u32 Index = 0);
|
||||||
|
void Delete(u32 Index);
|
||||||
|
|
||||||
|
u32 GetSize(void) const;
|
||||||
|
u32 GetSize(void);
|
||||||
|
private:
|
||||||
|
struct SLinearListNode {
|
||||||
|
_T Data;
|
||||||
|
struct SLinearListNode *Next;
|
||||||
|
};
|
||||||
|
typedef struct SLinearListNode TLinearListNode;
|
||||||
|
TLinearListNode *m_Data;
|
||||||
|
bool m_SizeCacheValid;
|
||||||
|
u32 m_SizeCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _T> CLinearList<_T>::CLinearList(void)
|
||||||
|
{
|
||||||
|
m_Data = 0;
|
||||||
|
m_SizeCacheValid = true;
|
||||||
|
m_SizeCache = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CLinearList<_T>::Push(const _T &Element)
|
||||||
|
{
|
||||||
|
if (m_Data == 0)
|
||||||
|
{
|
||||||
|
m_Data = (TLinearListNode *)kmalloc(sizeof(TLinearListNode));
|
||||||
|
m_Data->Data = Element;
|
||||||
|
m_Data->Next = 0;
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinearListNode *LastNode = m_Data;
|
||||||
|
while (LastNode->Next != 0)
|
||||||
|
LastNode = LastNode->Next;
|
||||||
|
|
||||||
|
TLinearListNode *NewNode =
|
||||||
|
(TLinearListNode *)kmalloc(sizeof(TLinearListNode));
|
||||||
|
NewNode->Data = Element;
|
||||||
|
NewNode->Next = 0;
|
||||||
|
LastNode->Next = NewNode;
|
||||||
|
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CLinearList<_T>::Pop(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Data != 0);
|
||||||
|
if (m_Data->Next == 0)
|
||||||
|
{
|
||||||
|
_T &Element = m_Data->Data;
|
||||||
|
kfree((void*)m_Data);
|
||||||
|
m_Data = 0;
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
return Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinearListNode *LastNode = m_Data;
|
||||||
|
while (LastNode->Next->Next != 0)
|
||||||
|
LastNode = LastNode ->Next;
|
||||||
|
|
||||||
|
_T &Element = LastNode->Next->Data;
|
||||||
|
kfree((void*)LastNode->Next);
|
||||||
|
LastNode->Next = 0;
|
||||||
|
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
|
||||||
|
return Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CLinearList<_T>::operator[](u32 Index)
|
||||||
|
{
|
||||||
|
ASSERT(m_Data != 0);
|
||||||
|
TLinearListNode *Node = m_Data;
|
||||||
|
for (u32 i = 0; i < Index; i++)
|
||||||
|
{
|
||||||
|
Node = Node->Next;
|
||||||
|
ASSERT(Node != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Node->Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CLinearList<_T>::operator[](u32 Index) const
|
||||||
|
{
|
||||||
|
ASSERT(m_Data != 0);
|
||||||
|
TLinearListNode *Node = m_Data;
|
||||||
|
for (u32 i = 0; i < Index; i++)
|
||||||
|
{
|
||||||
|
Node = Node->Next;
|
||||||
|
ASSERT(Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Node->Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CLinearList<_T>::Insert(
|
||||||
|
const _T &Element, u32 Index)
|
||||||
|
{
|
||||||
|
if (m_Data == 0 && Index == 0)
|
||||||
|
{
|
||||||
|
Push(Element);
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(m_Data);
|
||||||
|
|
||||||
|
TLinearListNode *NodeBefore;
|
||||||
|
for (u32 i = 0; i < Index - 1; i++)
|
||||||
|
{
|
||||||
|
NodeBefore = NodeBefore->Next;
|
||||||
|
ASSERT(NodeBefore);
|
||||||
|
}
|
||||||
|
// Last node?
|
||||||
|
if (NodeBefore->Next == 0)
|
||||||
|
{
|
||||||
|
Push(Element);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinearListNode *NodeAfter = NodeBefore->Next;
|
||||||
|
|
||||||
|
TLinearListNode *NewNode = (TLinearListNode*)
|
||||||
|
kmalloc(sizeof(TLinearListNode));
|
||||||
|
NewNode->Data = Element;
|
||||||
|
NewNode->Next = NodeAfter;
|
||||||
|
NodeBefore->Next = NewNode;
|
||||||
|
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CLinearList<_T>::Delete(u32 Index)
|
||||||
|
{
|
||||||
|
if (m_Data == 0 && Index == 0)
|
||||||
|
{
|
||||||
|
Pop();
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ASSERT(m_Data);
|
||||||
|
|
||||||
|
TLinearListNode *NodeBefore = m_Data;
|
||||||
|
for (u32 i = 0; i < Index - 1; i++)
|
||||||
|
{
|
||||||
|
NodeBefore = NodeBefore->Next;
|
||||||
|
ASSERT(NodeBefore);
|
||||||
|
}
|
||||||
|
|
||||||
|
TLinearListNode *NodeToBeDeleted = NodeBefore->Next;
|
||||||
|
ASSERT(NodeToBeDeleted);
|
||||||
|
TLinearListNode *NodeAfter = NodeToBeDeleted->Next;
|
||||||
|
kfree((void*)NodeToBeDeleted);
|
||||||
|
NodeBefore->Next = NodeAfter;
|
||||||
|
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> u32 CLinearList<_T>::GetSize(void) const
|
||||||
|
{
|
||||||
|
if (m_SizeCacheValid)
|
||||||
|
return m_SizeCache;
|
||||||
|
|
||||||
|
TLinearListNode *Node = m_Data;
|
||||||
|
u32 Size = 1;
|
||||||
|
while (Node->Next != 0)
|
||||||
|
{
|
||||||
|
Node = Node->Next;
|
||||||
|
Size++;
|
||||||
|
}
|
||||||
|
return m_SizeCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> u32 CLinearList<_T>::GetSize(void)
|
||||||
|
{
|
||||||
|
if (m_SizeCacheValid)
|
||||||
|
return m_SizeCache;
|
||||||
|
|
||||||
|
if (m_Data == 0)
|
||||||
|
{
|
||||||
|
m_SizeCache = 0;
|
||||||
|
m_SizeCacheValid = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Size = 1;
|
||||||
|
TLinearListNode *Node = m_Data;
|
||||||
|
while (Node->Next != 0)
|
||||||
|
{
|
||||||
|
Node = Node->Next;
|
||||||
|
Size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SizeCache = Size;
|
||||||
|
m_SizeCacheValid = true;
|
||||||
|
return m_SizeCache;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,9 +1,19 @@
|
||||||
#ifndef __CVECTOR_H__
|
#ifndef __CVECTOR_H__
|
||||||
#define __CVECTOR_H__
|
#define __CVECTOR_H__
|
||||||
|
|
||||||
class cb {
|
#include "types.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "Tier0/heap.h"
|
||||||
|
#include "Tier0/panic.h"
|
||||||
|
#include "Tier0/kstdlib.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CVECTOR_MEMCPY_ELEMENTS
|
||||||
|
|
||||||
|
namespace cb {
|
||||||
// An STL-like vector implementation for internal use in the kernel
|
// An STL-like vector implementation for internal use in the kernel
|
||||||
template <typename _T> class CVector {
|
template <class _T> class CVector {
|
||||||
public:
|
public:
|
||||||
CVector(u32 StartElements = 32);
|
CVector(u32 StartElements = 32);
|
||||||
~CVector(void);
|
~CVector(void);
|
||||||
|
@ -24,23 +34,147 @@ class cb {
|
||||||
u32 Size(void);
|
u32 Size(void);
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
u32 Find(const _T &Element) const;
|
s32 Find(const _T &Element) const;
|
||||||
bool HasElement(const _T &Element) const;
|
bool HasElement(const _T &Element) const;
|
||||||
|
|
||||||
// Stack-like properties
|
// Stack-like properties
|
||||||
void Push(const _T &Element);
|
void Push(const _T &Element);
|
||||||
void PushNew(void);
|
void PushNew(void);
|
||||||
_T &Pop(void);
|
_T &Pop(void);
|
||||||
|
|
||||||
// Used for iteration... I could use another class unstead of u32's,
|
|
||||||
// but who cares :V
|
|
||||||
u32 IterationStart(void);
|
|
||||||
u32 IterationEnd(void);
|
|
||||||
protected:
|
protected:
|
||||||
_T *m_Members;
|
_T *m_Members;
|
||||||
u32 m_Size;
|
u32 m_Size;
|
||||||
u32 m_MemorySize;
|
u32 m_MemorySize;
|
||||||
|
|
||||||
|
// Pretty self-descriptive
|
||||||
|
void MoarMemoryPlox(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class _T> CVector<_T>::CVector(u32 StartElements)
|
||||||
|
{
|
||||||
|
m_MemorySize = StartElements;
|
||||||
|
m_Size = 0;
|
||||||
|
|
||||||
|
if (m_MemorySize > 0)
|
||||||
|
m_Members = (_T*)kmalloc(m_MemorySize * sizeof(_T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> CVector<_T>::~CVector(void)
|
||||||
|
{
|
||||||
|
if (m_MemorySize > 0)
|
||||||
|
kfree(m_Members);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::operator[](u32 Index)
|
||||||
|
{
|
||||||
|
ASSERT(Index < m_Size);
|
||||||
|
return m_Members[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CVector<_T>::operator[](u32 Index) const
|
||||||
|
{
|
||||||
|
ASSERT(Index < m_Size);
|
||||||
|
return m_Members[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::Head(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[Size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CVector<_T>::Head(void) const
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[Size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::Tail(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CVector<_T>::Tail(void) const
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T *CVector<_T>::BaseAddress(void)
|
||||||
|
{
|
||||||
|
return m_Members;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T *CVector<_T>::BaseAddress(void) const
|
||||||
|
{
|
||||||
|
return m_Members;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> u32 CVector<_T>::Size(void)
|
||||||
|
{
|
||||||
|
return m_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> s32 CVector<_T>::Find(const _T &Element) const
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < Size(); i++)
|
||||||
|
if (m_Members[i] == Element)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> bool CVector<_T>::HasElement(const _T &Element) const
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < Size(); i++)
|
||||||
|
if (m_Members[i] == Element)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::Pop(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CVector<_T>::MoarMemoryPlox(void)
|
||||||
|
{
|
||||||
|
u32 NewSize = m_MemorySize * 2;
|
||||||
|
|
||||||
|
_T *NewData = (_T*)kmalloc(NewSize * sizeof(_T));
|
||||||
|
|
||||||
|
// Copy the data over
|
||||||
|
kmemcpy((void*)NewData, (void*)m_Members, m_MemorySize * sizeof(_T));
|
||||||
|
|
||||||
|
kfree(m_Members);
|
||||||
|
m_Members = NewData;
|
||||||
|
|
||||||
|
m_MemorySize = NewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CVector<_T>::Push(const _T &Element)
|
||||||
|
{
|
||||||
|
if (m_Size + 1 > m_MemorySize)
|
||||||
|
MoarMemoryPlox();
|
||||||
|
|
||||||
|
#ifdef CVECTOR_MEMCPY_ELEMENTS
|
||||||
|
kmemcpy((void*)(m_Members + m_Size), (void*)&Element, sizeof(_T));
|
||||||
|
#else
|
||||||
|
m_Members[m_Size] = Element;
|
||||||
|
#endif
|
||||||
|
m_Size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CVector<_T>::PushNew(void)
|
||||||
|
{
|
||||||
|
if (m_Size + 1 > m_MemorySize)
|
||||||
|
MoarMemoryPlox();
|
||||||
|
|
||||||
|
(m_Members + m_Size) = new _T();
|
||||||
|
|
||||||
|
m_Size++;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#ifndef __TYPES_H__
|
#ifndef __TYPES_H__
|
||||||
#define __TYPES_H__
|
#define __TYPES_H__
|
||||||
|
|
||||||
|
typedef unsigned long long u64;
|
||||||
typedef unsigned int u32;
|
typedef unsigned int u32;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "Tier1/CPageDirectory.h"
|
#include "Tier1/CPageDirectory.h"
|
||||||
#include "Tier1/CTask.h"
|
#include "Tier1/CTask.h"
|
||||||
#include "Tier1/CScheduler.h"
|
#include "Tier1/CScheduler.h"
|
||||||
|
#include "Tier1/Util/CVector.h"
|
||||||
|
#include "Tier1/Util/CLinearList.h"
|
||||||
using namespace cb;
|
using namespace cb;
|
||||||
|
|
||||||
CKernel g_Kernel;
|
CKernel g_Kernel;
|
||||||
|
@ -55,6 +57,8 @@ void CKernel::Start(void)
|
||||||
CScheduler::AddTask(KernelTask);
|
CScheduler::AddTask(KernelTask);
|
||||||
CScheduler::Enable();
|
CScheduler::Enable();
|
||||||
|
|
||||||
|
//PANIC("I LIKE THE COCK");
|
||||||
|
|
||||||
CTask *ParentTask = CScheduler::GetCurrentTask();
|
CTask *ParentTask = CScheduler::GetCurrentTask();
|
||||||
CTask *NewTask = ParentTask->Fork();
|
CTask *NewTask = ParentTask->Fork();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "Tier1/CRoundRobinScheduler.h"
|
||||||
|
using namespace cb;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "Tier0/panic.h"
|
||||||
|
#include "Tier0/kstdio.h"
|
||||||
|
#include "Tier0/heap.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRoundRobinScheduler::Enable(bool Enabled)
|
||||||
|
{
|
||||||
|
m_TaskQueuePosition = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((optimize("O0"))) void CRoundRobinScheduler::NextTask(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile("cli");
|
||||||
|
volatile u32 NewEBP, NewESP, NewEIP, EBP, ESP, Directory;
|
||||||
|
|
||||||
|
if (m_TaskQueue.GetSize() == 0)
|
||||||
|
PANIC("No tasks in queue!");
|
||||||
|
|
||||||
|
// Fetch next task.
|
||||||
|
m_TaskQueuePosition++;
|
||||||
|
if (m_TaskQueuePosition >= m_TaskQueue.GetSize())
|
||||||
|
// Something happened - restart the queue
|
||||||
|
m_TaskQueuePosition = 0;
|
||||||
|
CTask *NextTask = m_TaskQueue[m_TaskQueuePosition];
|
||||||
|
|
||||||
|
// Read task details
|
||||||
|
NewEBP = NextTask->GetEBP();
|
||||||
|
NewESP = NextTask->GetESP();
|
||||||
|
NewEIP = NextTask->GetEIP();
|
||||||
|
|
||||||
|
if (!NewEIP || !NewESP || !NewEBP)
|
||||||
|
{
|
||||||
|
kprintf("[i] no wai\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save current task details
|
||||||
|
__asm__ volatile("mov %%esp, %0" : "=r"(ESP));
|
||||||
|
__asm__ volatile("mov %%ebp, %0" : "=r"(EBP));
|
||||||
|
m_CurrentTask->SetEBP(EBP);
|
||||||
|
m_CurrentTask->SetESP(ESP);
|
||||||
|
|
||||||
|
// Return point
|
||||||
|
volatile u32 ReturnPoint = ctask_geteip();
|
||||||
|
//kprintf("return point %x\n", ReturnPoint);
|
||||||
|
|
||||||
|
if (ReturnPoint == 0xFEEDFACE)
|
||||||
|
{
|
||||||
|
//We are in the next task already
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CurrentTask->SetEIP(ReturnPoint);
|
||||||
|
|
||||||
|
// Switch to next task
|
||||||
|
m_CurrentTask = NextTask;
|
||||||
|
|
||||||
|
Directory = NextTask->GetPageDirectoryPhysicalAddress();
|
||||||
|
//kprintf("[i] I was told to jump to %x (%x %x); %x\n", NewEIP, NewESP,
|
||||||
|
// NewEBP, Directory);
|
||||||
|
//for(;;){}
|
||||||
|
interrupts_irq_finish(0);
|
||||||
|
|
||||||
|
__asm__ volatile("movl %1, %%esp\n"
|
||||||
|
"movl %2, %%ebp\n"
|
||||||
|
"movl %3, %%cr3\n"
|
||||||
|
"movl %0, %%ecx\n"
|
||||||
|
"movl $0xFEEDFACE, %%eax\n"
|
||||||
|
"jmp *%%ecx" ::
|
||||||
|
"r"(NewEIP),
|
||||||
|
"r"(NewESP),
|
||||||
|
"r"(NewEBP),
|
||||||
|
"r"(Directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRoundRobinScheduler::AddTask(CTask *Task)
|
||||||
|
{
|
||||||
|
__asm__ volatile("cli");
|
||||||
|
m_TaskQueue.Push(Task);
|
||||||
|
__asm__ volatile("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
CTask *CRoundRobinScheduler::GetCurrentTask(void)
|
||||||
|
{
|
||||||
|
return m_CurrentTask;
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
#include "Tier1/CScheduler.h"
|
#include "Tier1/CScheduler.h"
|
||||||
using namespace cb;
|
using namespace cb;
|
||||||
|
|
||||||
|
#include "Tier1/CRoundRobinScheduler.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "Tier0/heap.h"
|
#include "Tier0/heap.h"
|
||||||
#include "Tier0/panic.h"
|
#include "Tier0/panic.h"
|
||||||
|
@ -11,111 +13,20 @@ CScheduler g_Scheduler;
|
||||||
|
|
||||||
CScheduler::CScheduler(void)
|
CScheduler::CScheduler(void)
|
||||||
{
|
{
|
||||||
m_CurrentTask = 0;
|
m_CurrentScheduler = new CRoundRobinScheduler();
|
||||||
m_TaskQueueStart = 0;
|
m_CurrentScheduler->Enable(true);
|
||||||
m_TaskQueueCurrent = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScheduler::AddTask(CTask *Task)
|
void CScheduler::AddTask(CTask *Task)
|
||||||
{
|
{
|
||||||
__asm__ volatile("cli");
|
__asm__ volatile("cli");
|
||||||
TTaskQueueNode *Current = g_Scheduler.m_TaskQueueStart;
|
g_Scheduler.m_CurrentScheduler->AddTask(Task);
|
||||||
|
|
||||||
if (Current == 0)
|
|
||||||
{
|
|
||||||
g_Scheduler.m_TaskQueueCurrent = (TTaskQueueNode*)
|
|
||||||
kmalloc(sizeof(TTaskQueueNode));
|
|
||||||
g_Scheduler.m_TaskQueueCurrent->Task = Task;
|
|
||||||
g_Scheduler.m_TaskQueueCurrent->Next = 0;
|
|
||||||
g_Scheduler.m_TaskQueueStart = g_Scheduler.m_TaskQueueCurrent;
|
|
||||||
g_Scheduler.m_CurrentTask = Task;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (Current->Next != 0)
|
|
||||||
Current = Current->Next;
|
|
||||||
|
|
||||||
// We are now at the last node.
|
|
||||||
Current->Next = (TTaskQueueNode*)kmalloc(sizeof(TTaskQueueNode));
|
|
||||||
Current->Next->Task = Task;
|
|
||||||
Current->Next->Next = 0;
|
|
||||||
__asm__ volatile("sti");
|
__asm__ volatile("sti");
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC optimize ("O0")
|
|
||||||
|
|
||||||
__attribute__((optimize("O0"))) void CScheduler::NextTask(void)
|
|
||||||
{
|
|
||||||
__asm__ volatile("cli");
|
|
||||||
volatile u32 NewEBP, NewESP, NewEIP, EBP, ESP, Directory;
|
|
||||||
TTaskQueueNode *Next;
|
|
||||||
|
|
||||||
/*if (g_Scheduler.m_TaskQueueStart == 0)
|
|
||||||
PANIC("No tasks in queue!");
|
|
||||||
|
|
||||||
if (g_Scheduler.m_TaskQueueCurrent == 0)
|
|
||||||
PANIC("Current task is null!");*/
|
|
||||||
|
|
||||||
// Fetch next task.
|
|
||||||
if (g_Scheduler.m_TaskQueueCurrent->Next == 0)
|
|
||||||
Next = g_Scheduler.m_TaskQueueStart;
|
|
||||||
else
|
|
||||||
Next = g_Scheduler.m_TaskQueueCurrent->Next;
|
|
||||||
|
|
||||||
// Read task details
|
|
||||||
NewEBP = Next->Task->m_EBP;
|
|
||||||
NewESP = Next->Task->m_ESP;
|
|
||||||
NewEIP = Next->Task->m_EIP;
|
|
||||||
|
|
||||||
if (!NewEIP || !NewESP || !NewEBP)
|
|
||||||
{
|
|
||||||
kprintf("[i] no wai\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save current task details
|
|
||||||
__asm__ volatile("mov %%esp, %0" : "=r"(ESP));
|
|
||||||
__asm__ volatile("mov %%ebp, %0" : "=r"(EBP));
|
|
||||||
g_Scheduler.m_CurrentTask->m_EBP = EBP;
|
|
||||||
g_Scheduler.m_CurrentTask->m_ESP = ESP;
|
|
||||||
|
|
||||||
// Return point
|
|
||||||
volatile u32 ReturnPoint = ctask_geteip();
|
|
||||||
//kprintf("return point %x\n", ReturnPoint);
|
|
||||||
|
|
||||||
if (ReturnPoint == 0xFEEDFACE)
|
|
||||||
{
|
|
||||||
//We are in the next task already
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Scheduler.m_CurrentTask->m_EIP = ReturnPoint;
|
|
||||||
|
|
||||||
// Switch to next task
|
|
||||||
g_Scheduler.m_TaskQueueCurrent = Next;
|
|
||||||
g_Scheduler.m_CurrentTask = Next->Task;
|
|
||||||
|
|
||||||
Directory = Next->Task->m_Directory->m_Directory->PhysicalAddress;
|
|
||||||
//kprintf("[i] I was told to jump to %x (%x %x); %x\n", NewEIP, NewESP,
|
|
||||||
// NewEBP, Directory);
|
|
||||||
//for(;;){}
|
|
||||||
interrupts_irq_finish(0);
|
|
||||||
|
|
||||||
__asm__ volatile("movl %1, %%esp\n"
|
|
||||||
"movl %2, %%ebp\n"
|
|
||||||
"movl %3, %%cr3\n"
|
|
||||||
"movl %0, %%ecx\n"
|
|
||||||
"movl $0xFEEDFACE, %%eax\n"
|
|
||||||
"jmp *%%ecx" ::
|
|
||||||
"r"(NewEIP),
|
|
||||||
"r"(NewESP),
|
|
||||||
"r"(NewEBP),
|
|
||||||
"r"(Directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
CTask *CScheduler::GetCurrentTask(void)
|
CTask *CScheduler::GetCurrentTask(void)
|
||||||
{
|
{
|
||||||
return g_Scheduler.m_CurrentTask;
|
return g_Scheduler.m_CurrentScheduler->GetCurrentTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScheduler::Enable(void)
|
void CScheduler::Enable(void)
|
||||||
|
@ -132,5 +43,5 @@ void CScheduler::Enable(void)
|
||||||
|
|
||||||
void CScheduler::TimerTick(T_ISR_REGISTERS R)
|
void CScheduler::TimerTick(T_ISR_REGISTERS R)
|
||||||
{
|
{
|
||||||
NextTask();
|
g_Scheduler.m_CurrentScheduler->NextTask();
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,8 +131,3 @@ void CTask::Dump(void)
|
||||||
m_ESP, m_EBP, m_EIP);
|
m_ESP, m_EBP, m_EIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CTask::GetPID(void)
|
|
||||||
{
|
|
||||||
return m_PID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,133 @@
|
||||||
#include "Tier1/Utils/CVector.h"
|
/*#include "Tier1/Util/CVector.h"
|
||||||
using namespace cb;
|
using namespace cb;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "Tier0/heap.h"
|
#include "Tier0/heap.h"
|
||||||
|
#include "Tier0/panic.h"
|
||||||
|
#include "Tier0/kstdlib.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define tmpl template <typename _T>
|
template <class _T> CVector<_T>::CVector(u32 StartElements)
|
||||||
|
|
||||||
tmpl CVector::CVector(u32 StartElements)
|
|
||||||
{
|
{
|
||||||
m_Size = m_MemorySize = StartElements;
|
m_Size = m_MemorySize = StartElements;
|
||||||
|
|
||||||
if (m_Size > 0)
|
if (m_Size > 0)
|
||||||
m_Members = (_T*)malloc(m_Size * sizeof(_T));
|
m_Members = (_T*)kmalloc(m_Size * sizeof(_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl CVector::~CVector(void)
|
template <class _T> CVector<_T>::~CVector(void)
|
||||||
{
|
{
|
||||||
if (m_MemorySize > 0)
|
if (m_MemorySize > 0)
|
||||||
|
kfree(m_Members);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::operator[](u32 Index)
|
||||||
|
{
|
||||||
|
ASSERT(Index < m_Size);
|
||||||
|
return m_Members[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CVector<_T>::operator[](u32 Index) const
|
||||||
|
{
|
||||||
|
ASSERT(Index < m_Size);
|
||||||
|
return m_Members[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::Head(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[Size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CVector<_T>::Head(void) const
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[Size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::Tail(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T &CVector<_T>::Tail(void) const
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
return m_Members[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T *CVector<_T>::BaseAddress(void)
|
||||||
|
{
|
||||||
|
return m_Members;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> const _T *CVector<_T>::BaseAddress(void) const
|
||||||
|
{
|
||||||
|
return m_Members;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> u32 CVector<_T>::Size(void)
|
||||||
|
{
|
||||||
|
return m_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> s32 CVector<_T>::Find(const _T &Element) const
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < Size(); i++)
|
||||||
|
if (m_Members[i] == Element)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> bool CVector<_T>::HasElement(const _T &Element) const
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < Size(); i++)
|
||||||
|
if (m_Members[i] == Element)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> _T &CVector<_T>::Pop(void)
|
||||||
|
{
|
||||||
|
ASSERT(m_Size > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _T> void CVector<_T>::MoarMemoryPlox(void)
|
||||||
|
{
|
||||||
|
u32 NewSize = m_MemorySize * 2;
|
||||||
|
|
||||||
|
_T *NewData = (_T*)kmalloc(NewSize * sizeof(_T));
|
||||||
|
|
||||||
|
// Copy the data over
|
||||||
|
kmemcpy((void*)NewData, (void*)m_Members, m_MemorySize * sizeof(_T));
|
||||||
|
|
||||||
|
kfree(m_Members);
|
||||||
|
m_Members = NewData;
|
||||||
|
|
||||||
|
m_MemorySize = NewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CVector<_T>::Push(const _T &Element)
|
||||||
|
{
|
||||||
|
if (m_Size + 1 > m_MemorySize)
|
||||||
|
MoarMemoryPlox();
|
||||||
|
|
||||||
|
#ifdef CVECTOR_MEMCPY_ELEMENTS
|
||||||
|
kmemcpy((void*)(m_Members + m_Size), (void*)&Element, sizeof(_T));
|
||||||
|
#else
|
||||||
|
m_Members[m_Size] = Element;
|
||||||
|
#endif
|
||||||
|
m_Size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _T> void CVector<_T>::PushNew(void)
|
||||||
|
{
|
||||||
|
if (m_Size + 1 > m_MemorySize)
|
||||||
|
MoarMemoryPlox();
|
||||||
|
|
||||||
|
(m_Members + m_Size) = new _T();
|
||||||
|
|
||||||
|
m_Size++;
|
||||||
|
}*/
|
||||||
|
|
Loading…
Reference in New Issue