penis
parent
b1892a7e82
commit
07f4f66ba5
1
Makefile
1
Makefile
|
@ -43,6 +43,7 @@ obj/src/%.o : src/%.c
|
|||
|
||||
obj/src/%.xo : src/%.cpp
|
||||
@echo "[i] Compiling $*.cpp ..."
|
||||
@if [ -e obj/src/$*.xo ] ; then rm obj/src/$*.xo ; fi
|
||||
@mkdir -p obj/src/$*.xo
|
||||
@rmdir 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 "Tier1/CTask.h"
|
||||
#include "Tier1/IScheduler.h"
|
||||
|
||||
extern "C" {
|
||||
#include "Tier0/interrupts.h"
|
||||
|
@ -16,17 +17,13 @@ namespace cb {
|
|||
} TTaskQueueNode;
|
||||
class CScheduler {
|
||||
private:
|
||||
CTask *m_CurrentTask;
|
||||
|
||||
TTaskQueueNode *m_TaskQueueStart;
|
||||
TTaskQueueNode *m_TaskQueueCurrent;
|
||||
IScheduler *m_CurrentScheduler;
|
||||
|
||||
static void TimerTick(T_ISR_REGISTERS R);
|
||||
public:
|
||||
CScheduler(void);
|
||||
static void Enable(void);
|
||||
static void AddTask(CTask *Task);
|
||||
static void NextTask(void);
|
||||
static CTask *GetCurrentTask(void);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -129,7 +129,25 @@ namespace cb {
|
|||
// Equivalent of the POSIX fork() call.
|
||||
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);
|
||||
|
||||
|
|
|
@ -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__
|
||||
#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
|
||||
template <typename _T> class CVector {
|
||||
template <class _T> class CVector {
|
||||
public:
|
||||
CVector(u32 StartElements = 32);
|
||||
~CVector(void);
|
||||
|
@ -24,23 +34,147 @@ class cb {
|
|||
u32 Size(void);
|
||||
|
||||
// Search
|
||||
u32 Find(const _T &Element) const;
|
||||
s32 Find(const _T &Element) const;
|
||||
bool HasElement(const _T &Element) const;
|
||||
|
||||
// Stack-like properties
|
||||
void Push(const _T &Element);
|
||||
void PushNew(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:
|
||||
_T *m_Members;
|
||||
u32 m_Size;
|
||||
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
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
typedef unsigned long long u64;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "Tier1/CPageDirectory.h"
|
||||
#include "Tier1/CTask.h"
|
||||
#include "Tier1/CScheduler.h"
|
||||
#include "Tier1/Util/CVector.h"
|
||||
#include "Tier1/Util/CLinearList.h"
|
||||
using namespace cb;
|
||||
|
||||
CKernel g_Kernel;
|
||||
|
@ -55,6 +57,8 @@ void CKernel::Start(void)
|
|||
CScheduler::AddTask(KernelTask);
|
||||
CScheduler::Enable();
|
||||
|
||||
//PANIC("I LIKE THE COCK");
|
||||
|
||||
CTask *ParentTask = CScheduler::GetCurrentTask();
|
||||
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"
|
||||
using namespace cb;
|
||||
|
||||
#include "Tier1/CRoundRobinScheduler.h"
|
||||
|
||||
extern "C" {
|
||||
#include "Tier0/heap.h"
|
||||
#include "Tier0/panic.h"
|
||||
|
@ -11,111 +13,20 @@ CScheduler g_Scheduler;
|
|||
|
||||
CScheduler::CScheduler(void)
|
||||
{
|
||||
m_CurrentTask = 0;
|
||||
m_TaskQueueStart = 0;
|
||||
m_TaskQueueCurrent = 0;
|
||||
m_CurrentScheduler = new CRoundRobinScheduler();
|
||||
m_CurrentScheduler->Enable(true);
|
||||
}
|
||||
|
||||
void CScheduler::AddTask(CTask *Task)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
TTaskQueueNode *Current = g_Scheduler.m_TaskQueueStart;
|
||||
|
||||
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;
|
||||
g_Scheduler.m_CurrentScheduler->AddTask(Task);
|
||||
__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)
|
||||
{
|
||||
return g_Scheduler.m_CurrentTask;
|
||||
return g_Scheduler.m_CurrentScheduler->GetCurrentTask();
|
||||
}
|
||||
|
||||
void CScheduler::Enable(void)
|
||||
|
@ -132,5 +43,5 @@ void CScheduler::Enable(void)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
u32 CTask::GetPID(void)
|
||||
{
|
||||
return m_PID;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,133 @@
|
|||
#include "Tier1/Utils/CVector.h"
|
||||
/*#include "Tier1/Util/CVector.h"
|
||||
using namespace cb;
|
||||
|
||||
extern "C" {
|
||||
#include "Tier0/heap.h"
|
||||
#include "Tier0/panic.h"
|
||||
#include "Tier0/kstdlib.h"
|
||||
};
|
||||
|
||||
#define tmpl template <typename _T>
|
||||
|
||||
tmpl CVector::CVector(u32 StartElements)
|
||||
template <class _T> CVector<_T>::CVector(u32 StartElements)
|
||||
{
|
||||
m_Size = m_MemorySize = StartElements;
|
||||
|
||||
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)
|
||||
|
||||
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