Some scheduler fixes.
parent
11cf26eb54
commit
164ea30d44
|
@ -1,7 +1,7 @@
|
||||||
#Sun May 08 13:56:50 CEST 2011
|
#Sun May 08 17:23:22 CEST 2011
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/PATH/delimiter=;
|
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/PATH/delimiter=;
|
||||||
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/PATH/operation=replace
|
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/PATH/operation=replace
|
||||||
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/PATH/value=C\:\\cygwin\\bin;C\:\\Windows\\system32;C\:\\Windows;
|
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/PATH/value=C\:\\Development\\qemu;C\:\\cygwin\\bin;C\:\\Windows\\system32;C\:\\Windows;
|
||||||
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/append=true
|
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/append=true
|
||||||
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/appendContributed=true
|
environment/project/cdt.managedbuild.toolchain.gnu.mingw.base.561123667/appendContributed=true
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@
|
||||||
# Seriously.
|
# Seriously.
|
||||||
#
|
#
|
||||||
# Fuck M4. I do this because it's probably the most portable way, and I don't
|
# Fuck M4. I do this because it's probably the most portable way, and I don't
|
||||||
# wan't to write Yet Another Compile System because fuck that shit. I could
|
# want to write Yet Another Compile System because fuck that shit. I could
|
||||||
# use cmake but I don't know whether it is flexible enough. It probably is
|
# use cmake but I don't know whether it is flexible enough. It probably is
|
||||||
# but whatever. I wrote this piece of shit below, let's just keep it that
|
# but whatever. I wrote this piece of shit below, let's just keep it that
|
||||||
# way. There are better way to do the hthings I do below, but who gives a
|
# way. There are better way to do the hthings I do below, but who gives a
|
||||||
|
|
|
@ -9,13 +9,16 @@ namespace cb {
|
||||||
public:
|
public:
|
||||||
void Enable(bool Enabled);
|
void Enable(bool Enabled);
|
||||||
void AddTask(CTask *Task);
|
void AddTask(CTask *Task);
|
||||||
void NextTask(void);
|
void NextTask(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip);
|
||||||
CTask *GetCurrentTask(void);
|
CTask *GetCurrentTask(void);
|
||||||
void SetSemaphoreAvailable(CSemaphore *Semaphore);
|
void SetSemaphoreAvailable(CSemaphore *Semaphore);
|
||||||
|
void PrioritizeTask(CTask *Task);
|
||||||
private:
|
private:
|
||||||
CTask *m_CurrentTask;
|
CTask *m_CurrentTask;
|
||||||
CLinearList<CTask *> m_TaskQueue;
|
CLinearList<CTask *> m_TaskQueue;
|
||||||
u32 m_iTaskQueuePosition;
|
u32 m_iTaskQueuePosition;
|
||||||
|
|
||||||
|
CTask *m_PrioritizedTask;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "Tier1/IScheduler.h"
|
#include "Tier1/IScheduler.h"
|
||||||
#include "Tier1/CSemaphore.h"
|
#include "Tier1/CSemaphore.h"
|
||||||
|
|
||||||
|
#define CSCHEDULER_INTERRUPT_YIELD 0x99
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "Tier0/interrupts.h"
|
#include "Tier0/interrupts.h"
|
||||||
}
|
}
|
||||||
|
@ -16,17 +18,21 @@ namespace cb {
|
||||||
CTask *Task;
|
CTask *Task;
|
||||||
struct STaskQueueNode *Next;
|
struct STaskQueueNode *Next;
|
||||||
} TTaskQueueNode;
|
} TTaskQueueNode;
|
||||||
class CScheduler {
|
class CScheduler{
|
||||||
private:
|
private:
|
||||||
IScheduler *m_CurrentScheduler;
|
IScheduler *m_CurrentScheduler;
|
||||||
|
|
||||||
static bool TimerTick(u32 Extra);
|
static void TimerTick(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip);
|
||||||
|
static void Yield(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip);
|
||||||
|
|
||||||
|
static u32 m_NumTicks;
|
||||||
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 CTask *GetCurrentTask(void);
|
static CTask *GetCurrentTask(void);
|
||||||
static void NextTask(void);
|
static void NextTask();
|
||||||
|
static void PrioritizeTask(CTask *Task);
|
||||||
|
|
||||||
static void DispatchAvailableSemaphore(CSemaphore *Semaphore);
|
static void DispatchAvailableSemaphore(CSemaphore *Semaphore);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern "C" {
|
||||||
|
|
||||||
namespace cb {
|
namespace cb {
|
||||||
class CSemaphore {
|
class CSemaphore {
|
||||||
private:
|
protected:
|
||||||
T_ATOMIC m_Available;
|
T_ATOMIC m_Available;
|
||||||
public:
|
public:
|
||||||
CSemaphore(u32 Available = 1);
|
CSemaphore(u32 Available = 1);
|
||||||
|
|
|
@ -3,34 +3,46 @@
|
||||||
|
|
||||||
#include "Tier1/CInterruptDispatcher.h"
|
#include "Tier1/CInterruptDispatcher.h"
|
||||||
#include "Tier1/Util/CLinearList.h"
|
#include "Tier1/Util/CLinearList.h"
|
||||||
|
#include "Tier1/CTask.h"
|
||||||
|
#include "Tier1/CSemaphore.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace cb {
|
namespace cb {
|
||||||
typedef bool(*TTimerCallback)(u32);
|
typedef bool(*TTimerCallback)(u32);
|
||||||
|
typedef void(*TTimerFastHook)(u32, u32, u32, u32, u32, u32, u32, u32, u32);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TTimerCallback Callback;
|
TTimerCallback Callback;
|
||||||
u32 Interval;
|
u32 Interval;
|
||||||
s32 Times;
|
s32 Times;
|
||||||
u32 NextCall;
|
u32 NextCall;
|
||||||
u32 Extra;
|
u32 Extra;
|
||||||
|
CTask *Task;
|
||||||
} TCallbackInfo;
|
} TCallbackInfo;
|
||||||
class CTimer {
|
class CTimer {
|
||||||
public:
|
public:
|
||||||
static void Create(u32 Interval, s32 Times, TTimerCallback Callback,
|
static void Create(u32 Interval, s32 Times, TTimerCallback Callback,
|
||||||
u32 Extra = 0);
|
u32 Extra = 0);
|
||||||
|
// This is like ::Create, but faster, and there can only be one, and it's fixed interval
|
||||||
|
static void SetFastTimerHook(TTimerFastHook Hook);
|
||||||
inline static u32 GetTicks(void)
|
inline static u32 GetTicks(void)
|
||||||
{
|
{
|
||||||
if (!m_bInitialized)
|
if (!m_bInitialized)
|
||||||
Initialize();
|
Initialize();
|
||||||
return m_nTicks;
|
m_GetTicksSemaphore.Acquire();
|
||||||
|
volatile u32 Ticks = m_nTicks;
|
||||||
|
m_GetTicksSemaphore.Release();
|
||||||
|
return Ticks;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static CLinearList<TCallbackInfo> m_Callbacks;
|
static CLinearList<TCallbackInfo> m_Callbacks;
|
||||||
volatile static u32 m_nTicks;
|
volatile static u32 m_nTicks;
|
||||||
static void Initialize(void);
|
static void Initialize(void);
|
||||||
static void Dispatch(void *Registers);
|
static void Dispatch(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip);
|
||||||
static bool m_bInitialized;
|
static bool m_bInitialized;
|
||||||
|
static TTimerFastHook m_FastHook;
|
||||||
|
|
||||||
|
static CSemaphore m_GetTicksSemaphore;
|
||||||
|
|
||||||
// Called when the number of ticks is just about to overflow.
|
// Called when the number of ticks is just about to overflow.
|
||||||
// Reschedules all the callbacks.
|
// Reschedules all the callbacks.
|
||||||
static void Reschedule(void);
|
static void Reschedule(void);
|
||||||
|
|
|
@ -9,9 +9,10 @@ namespace cb {
|
||||||
public:
|
public:
|
||||||
virtual void Enable(bool Enabled) = 0;
|
virtual void Enable(bool Enabled) = 0;
|
||||||
virtual void AddTask(CTask *Task) = 0;
|
virtual void AddTask(CTask *Task) = 0;
|
||||||
virtual void NextTask(void) = 0;
|
virtual void NextTask(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip) = 0;
|
||||||
virtual CTask *GetCurrentTask(void) = 0;
|
virtual CTask *GetCurrentTask(void) = 0;
|
||||||
virtual void SetSemaphoreAvailable(CSemaphore *Semaphore) = 0;
|
virtual void SetSemaphoreAvailable(CSemaphore *Semaphore) = 0;
|
||||||
|
virtual void PrioritizeTask(CTask *Task) = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ extern "C" {
|
||||||
#include "Tier0/heap.h"
|
#include "Tier0/heap.h"
|
||||||
#include "Tier0/panic.h"
|
#include "Tier0/panic.h"
|
||||||
#include "Tier0/kstdlib.h"
|
#include "Tier0/kstdlib.h"
|
||||||
|
#include "Tier0/kstdio.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace cb {
|
namespace cb {
|
||||||
|
@ -96,12 +97,18 @@ namespace cb {
|
||||||
|
|
||||||
template <class _T> _T &CLinearList<_T>::operator[](u32 Index)
|
template <class _T> _T &CLinearList<_T>::operator[](u32 Index)
|
||||||
{
|
{
|
||||||
ASSERT(m_Data != 0);
|
ASSERT(m_Data != 0);
|
||||||
TLinearListNode *Node = m_Data;
|
TLinearListNode *Node = m_Data;
|
||||||
for (u32 i = 0; i < Index; i++)
|
for (u32 i = 0; i < Index; i++)
|
||||||
{
|
{
|
||||||
Node = Node->Next;
|
Node = Node->Next;
|
||||||
ASSERT(Node != 0);
|
//ASSERT(Node != 0);
|
||||||
|
if (Node == 0)
|
||||||
|
{
|
||||||
|
kprintf("fail\n");
|
||||||
|
__asm__ volatile("cli");
|
||||||
|
for(;;){}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Node->Data;
|
return Node->Data;
|
||||||
|
@ -164,10 +171,25 @@ namespace cb {
|
||||||
m_SizeCacheValid = false;
|
m_SizeCacheValid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(m_Data != 0);
|
ASSERT(m_Data != 0);
|
||||||
|
|
||||||
|
if (Index == 0)
|
||||||
|
{
|
||||||
|
ASSERT(m_Data != 0);
|
||||||
|
|
||||||
|
TLinearListNode *ToBeDeleted = m_Data;
|
||||||
|
TLinearListNode *NodeAfter = m_Data->Next;
|
||||||
|
m_Data = NodeAfter;
|
||||||
|
|
||||||
|
kfree((void*)ToBeDeleted);
|
||||||
|
|
||||||
|
m_SizeCacheValid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TLinearListNode *NodeBefore = m_Data;
|
TLinearListNode *NodeBefore = m_Data;
|
||||||
for (u32 i = 0; i < Index - 1; i++)
|
for (s32 i = 0; i < (s32)Index - 1; i++)
|
||||||
{
|
{
|
||||||
NodeBefore = NodeBefore->Next;
|
NodeBefore = NodeBefore->Next;
|
||||||
ASSERT(NodeBefore != 0);
|
ASSERT(NodeBefore != 0);
|
||||||
|
|
|
@ -66,8 +66,12 @@ void CKernel::Start(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
CScheduler::GetCurrentTask()->Sleep(1000);
|
//CScheduler::GetCurrentTask()->Sleep(1000);
|
||||||
kprintf("[i] Hello! I'm the child process.\n");
|
for (volatile u32 i = 0; i < 14000; i++)
|
||||||
|
{
|
||||||
|
for (volatile u32 j = 0; j < 650; j++){}
|
||||||
|
}
|
||||||
|
kprintf("[i] Hello! I'm the child process %i.\n", CTimer::GetTicks());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,30 +10,43 @@ extern "C" {
|
||||||
void CRoundRobinScheduler::Enable(bool Enabled)
|
void CRoundRobinScheduler::Enable(bool Enabled)
|
||||||
{
|
{
|
||||||
m_iTaskQueuePosition = 0;
|
m_iTaskQueuePosition = 0;
|
||||||
|
m_PrioritizedTask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((optimize("O0"))) void CRoundRobinScheduler::NextTask(void)
|
__attribute__((optimize("O0"))) void CRoundRobinScheduler::NextTask(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip)
|
||||||
{
|
{
|
||||||
volatile u32 NewEBP, NewESP, NewEIP, EBP, ESP, Directory;
|
// A wild magic value appears!
|
||||||
|
esp += 12;
|
||||||
|
|
||||||
|
volatile u32 NewEBP, NewESP, NewEIP, Directory;
|
||||||
|
|
||||||
if (m_TaskQueue.GetSize() == 0)
|
if (m_TaskQueue.GetSize() < 1)
|
||||||
PANIC("No tasks in queue!");
|
PANIC("No tasks in queue!");
|
||||||
|
|
||||||
// Fetch next task.
|
// Fetch next task.
|
||||||
CTask *NextTask;
|
CTask *NextTask;
|
||||||
do {
|
/*if (m_PrioritizedTask != 0)
|
||||||
m_iTaskQueuePosition++;
|
{
|
||||||
|
NextTask = m_PrioritizedTask;
|
||||||
if (m_iTaskQueuePosition >= m_TaskQueue.GetSize())
|
m_PrioritizedTask = 0;
|
||||||
// Something happened - restart the queue
|
|
||||||
m_iTaskQueuePosition = 0;
|
|
||||||
NextTask = m_TaskQueue[m_iTaskQueuePosition];
|
|
||||||
}
|
}
|
||||||
while (NextTask->GetStatus() != ETS_RUNNING);
|
else
|
||||||
|
{*/
|
||||||
|
do {
|
||||||
|
m_iTaskQueuePosition++;
|
||||||
|
|
||||||
|
if (m_iTaskQueuePosition >= m_TaskQueue.GetSize())
|
||||||
|
// Something happened - restart the queue
|
||||||
|
m_iTaskQueuePosition = 0;
|
||||||
|
NextTask = m_TaskQueue[m_iTaskQueuePosition];
|
||||||
|
}
|
||||||
|
while (NextTask->GetStatus() != ETS_RUNNING);
|
||||||
|
//}
|
||||||
if (m_CurrentTask->GetPID() == NextTask->GetPID())
|
if (m_CurrentTask->GetPID() == NextTask->GetPID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//kprintf("switching from %x %x %x (%i to %i)\n", eip, esp, ebp, m_CurrentTask->GetPID(), NextTask->GetPID());
|
||||||
|
|
||||||
//kprintf("[i] %i -> %i (%x)\n", m_CurrentTask->GetPID(), NextTask->GetPID(), NextTask);
|
//kprintf("[i] %i -> %i (%x)\n", m_CurrentTask->GetPID(), NextTask->GetPID(), NextTask);
|
||||||
|
|
||||||
// Read task details
|
// Read task details
|
||||||
|
@ -47,26 +60,18 @@ __attribute__((optimize("O0"))) void CRoundRobinScheduler::NextTask(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save current task details
|
// Save current task details
|
||||||
__asm__ volatile("mov %%esp, %0" : "=r"(ESP));
|
m_CurrentTask->SetEBP(ebp);
|
||||||
__asm__ volatile("mov %%ebp, %0" : "=r"(EBP));
|
m_CurrentTask->SetESP(esp);
|
||||||
m_CurrentTask->SetEBP(EBP);
|
|
||||||
m_CurrentTask->SetESP(ESP);
|
|
||||||
|
|
||||||
// Return point
|
// Return point
|
||||||
volatile u32 ReturnPoint = ctask_geteip();
|
volatile u32 ReturnPoint = eip;
|
||||||
|
|
||||||
if (ReturnPoint == 0xFEEDFACE)
|
|
||||||
{
|
|
||||||
//We are in the next task already
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CurrentTask->SetEIP(ReturnPoint);
|
m_CurrentTask->SetEIP(ReturnPoint);
|
||||||
// Switch to next task
|
// Switch to next task
|
||||||
m_CurrentTask = NextTask;
|
m_CurrentTask = NextTask;
|
||||||
|
|
||||||
Directory = NextTask->GetPageDirectoryPhysicalAddress();
|
Directory = NextTask->GetPageDirectoryPhysicalAddress();
|
||||||
//kprintf("[i] I was told to jump to %x (%x %x); %x\n", NewEIP, NewESP,
|
//kprintf("[i] I was told to jump to %x (%x %x); %x\n", NewEIP, NewESP,
|
||||||
// NewEBP, Directory);
|
// NewEBP, Directory);
|
||||||
//for(;;){}
|
//for(;;){}
|
||||||
interrupts_irq_finish(0);
|
interrupts_irq_finish(0);
|
||||||
|
@ -75,7 +80,6 @@ __attribute__((optimize("O0"))) void CRoundRobinScheduler::NextTask(void)
|
||||||
"movl %2, %%ebp\n"
|
"movl %2, %%ebp\n"
|
||||||
"movl %3, %%cr3\n"
|
"movl %3, %%cr3\n"
|
||||||
"movl %0, %%ecx\n"
|
"movl %0, %%ecx\n"
|
||||||
"movl $0xFEEDFACE, %%eax\n"
|
|
||||||
"jmp *%%ecx" ::
|
"jmp *%%ecx" ::
|
||||||
"r"(NewEIP),
|
"r"(NewEIP),
|
||||||
"r"(NewESP),
|
"r"(NewESP),
|
||||||
|
@ -95,6 +99,11 @@ CTask *CRoundRobinScheduler::GetCurrentTask(void)
|
||||||
return m_CurrentTask;
|
return m_CurrentTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CRoundRobinScheduler::PrioritizeTask(CTask *Task)
|
||||||
|
{
|
||||||
|
m_PrioritizedTask = Task;
|
||||||
|
}
|
||||||
|
|
||||||
void CRoundRobinScheduler::SetSemaphoreAvailable(CSemaphore *Semaphore)
|
void CRoundRobinScheduler::SetSemaphoreAvailable(CSemaphore *Semaphore)
|
||||||
{
|
{
|
||||||
u32 Physical = GetCurrentTask()->GetPageDirectory()->
|
u32 Physical = GetCurrentTask()->GetPageDirectory()->
|
||||||
|
|
|
@ -3,14 +3,17 @@ using namespace cb;
|
||||||
|
|
||||||
#include "Tier1/CRoundRobinScheduler.h"
|
#include "Tier1/CRoundRobinScheduler.h"
|
||||||
#include "Tier1/CTimer.h"
|
#include "Tier1/CTimer.h"
|
||||||
|
#include "Tier1/CTask.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "Tier0/heap.h"
|
#include "Tier0/heap.h"
|
||||||
#include "Tier0/panic.h"
|
#include "Tier0/panic.h"
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
|
#include "Tier0/interrupts.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile CScheduler g_Scheduler;
|
volatile CScheduler g_Scheduler;
|
||||||
|
u32 CScheduler::m_NumTicks = 0;
|
||||||
|
|
||||||
CScheduler::CScheduler(void)
|
CScheduler::CScheduler(void)
|
||||||
{
|
{
|
||||||
|
@ -31,21 +34,42 @@ CTask *CScheduler::GetCurrentTask(void)
|
||||||
return g_Scheduler.m_CurrentScheduler->GetCurrentTask();
|
return g_Scheduler.m_CurrentScheduler->GetCurrentTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScheduler::PrioritizeTask(CTask *Task)
|
||||||
|
{
|
||||||
|
g_Scheduler.m_CurrentScheduler->PrioritizeTask(Task);
|
||||||
|
}
|
||||||
|
|
||||||
void CScheduler::Enable(void)
|
void CScheduler::Enable(void)
|
||||||
{
|
{
|
||||||
// 20ms quntum
|
CTimer::SetFastTimerHook(TimerTick);
|
||||||
CTimer::Create(200, -1, TimerTick);
|
|
||||||
|
// Add the Yield interrupt
|
||||||
|
interrupts_setup_isr(CSCHEDULER_INTERRUPT_YIELD, (void*)Yield, E_INTERRUPTS_RING0);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((optimize("O0"))) bool CScheduler::TimerTick(u32 Extra)
|
__attribute__((optimize("O0"))) void CScheduler::Yield(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip)
|
||||||
{
|
{
|
||||||
g_Scheduler.m_CurrentScheduler->NextTask();
|
__asm__ volatile("cli");
|
||||||
return true;
|
m_NumTicks = 0;
|
||||||
|
g_Scheduler.m_CurrentScheduler->NextTask(edi, esi, ebp, esp, ebx, edx, ecx, eax, eip);
|
||||||
|
__asm__ volatile("sti");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScheduler::NextTask(void)
|
__attribute__((optimize("O0"))) void CScheduler::TimerTick(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip)
|
||||||
{
|
{
|
||||||
g_Scheduler.m_CurrentScheduler->NextTask();
|
if (m_NumTicks > 20)
|
||||||
|
{
|
||||||
|
m_NumTicks = 0;
|
||||||
|
g_Scheduler.m_CurrentScheduler->NextTask(edi, esi, ebp, esp, ebx, edx, ecx, eax, eip);
|
||||||
|
}
|
||||||
|
m_NumTicks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((optimize("O0"))) void CScheduler::NextTask(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile("pusha");
|
||||||
|
__asm__ volatile ("int $0x99");
|
||||||
|
__asm__ volatile("popa");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScheduler::DispatchAvailableSemaphore(CSemaphore *Semaphore)
|
void CScheduler::DispatchAvailableSemaphore(CSemaphore *Semaphore)
|
||||||
|
|
|
@ -132,9 +132,11 @@ void CTask::Dump(void)
|
||||||
m_ESP, m_EBP, m_EIP);
|
m_ESP, m_EBP, m_EIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTask::Yield(void)
|
__attribute__((optimize("O0"))) void CTask::Yield(void)
|
||||||
{
|
{
|
||||||
|
//kprintf("Entering NextTask\n");
|
||||||
CScheduler::NextTask();
|
CScheduler::NextTask();
|
||||||
|
//kprintf("returned from NextTask\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTask::WaitForSemaphore(T_SEMAPHORE *Semaphore)
|
void CTask::WaitForSemaphore(T_SEMAPHORE *Semaphore)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "Tier1/CTimer.h"
|
#include "Tier1/CTimer.h"
|
||||||
|
#include "Tier1/CScheduler.h"
|
||||||
using namespace cb;
|
using namespace cb;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -6,9 +7,11 @@ extern "C" {
|
||||||
#include "Tier0/interrupts.h"
|
#include "Tier0/interrupts.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTimerFastHook CTimer::m_FastHook = 0;
|
||||||
volatile u32 CTimer::m_nTicks = 0;
|
volatile u32 CTimer::m_nTicks = 0;
|
||||||
bool CTimer::m_bInitialized = false;
|
bool CTimer::m_bInitialized = false;
|
||||||
CLinearList<TCallbackInfo> CTimer::m_Callbacks;
|
CLinearList<TCallbackInfo> CTimer::m_Callbacks;
|
||||||
|
CSemaphore CTimer::m_GetTicksSemaphore;
|
||||||
|
|
||||||
void CTimer::Initialize(void)
|
void CTimer::Initialize(void)
|
||||||
{
|
{
|
||||||
|
@ -23,9 +26,22 @@ void CTimer::Initialize(void)
|
||||||
m_bInitialized = true;
|
m_bInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTimer::Dispatch(void *Registers)
|
void CTimer::SetFastTimerHook(TTimerFastHook Hook)
|
||||||
|
{
|
||||||
|
__asm__ volatile("cli");
|
||||||
|
|
||||||
|
m_FastHook = Hook;
|
||||||
|
|
||||||
|
__asm__ volatile("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimer::Dispatch(u32 edi, u32 esi, u32 ebp, u32 esp, u32 ebx, u32 edx, u32 ecx, u32 eax, u32 eip)
|
||||||
{
|
{
|
||||||
__asm__ volatile("cli");
|
__asm__ volatile("cli");
|
||||||
|
|
||||||
|
if (m_FastHook)
|
||||||
|
(*m_FastHook)(edi, esi, ebp, esp, ebx, edx, ecx, eax, eip);
|
||||||
|
|
||||||
m_nTicks++;
|
m_nTicks++;
|
||||||
|
|
||||||
if (m_nTicks > (0xFFFFFFFF - 1000)) // 1000 ticks margin
|
if (m_nTicks > (0xFFFFFFFF - 1000)) // 1000 ticks margin
|
||||||
|
@ -49,8 +65,10 @@ void CTimer::Dispatch(void *Registers)
|
||||||
m_Callbacks.Delete(i);
|
m_Callbacks.Delete(i);
|
||||||
// TODO: fix this hack
|
// TODO: fix this hack
|
||||||
i--;
|
i--;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
// We can only take care of one timer callback...
|
||||||
|
CScheduler::PrioritizeTask(Callback.Task);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -63,6 +81,9 @@ void CTimer::Dispatch(void *Registers)
|
||||||
}
|
}
|
||||||
interrupts_irq_finish(0);
|
interrupts_irq_finish(0);
|
||||||
__asm__ volatile("sti");
|
__asm__ volatile("sti");
|
||||||
|
|
||||||
|
// Tough love for the current task.
|
||||||
|
//CScheduler::GetCurrentTask()->Yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTimer::Reschedule(void)
|
void CTimer::Reschedule(void)
|
||||||
|
@ -88,8 +109,10 @@ void CTimer::Create(u32 Interval, s32 Times, TTimerCallback Callback, u32 Extra)
|
||||||
NewCallback.Interval = Interval;
|
NewCallback.Interval = Interval;
|
||||||
NewCallback.Times = Times;
|
NewCallback.Times = Times;
|
||||||
NewCallback.Callback = Callback;
|
NewCallback.Callback = Callback;
|
||||||
NewCallback.NextCall = m_nTicks + Interval;
|
// Why minus 1? "Lag" compensation.
|
||||||
|
NewCallback.NextCall = m_nTicks + Interval - 1;
|
||||||
NewCallback.Extra = Extra;
|
NewCallback.Extra = Extra;
|
||||||
|
NewCallback.Task = CScheduler::GetCurrentTask();
|
||||||
|
|
||||||
m_Callbacks.Push(NewCallback);
|
m_Callbacks.Push(NewCallback);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue