From 1b7f774566434c25e280879c8e547620982c9f64 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 15 Mar 2014 15:58:05 +0800 Subject: [PATCH] Kernel - Expose thread timer for EVENT_TIMER, multiple sleepers for workqueue, cleanup of Threads_int_Sleep --- KernelLand/Kernel/include/acess.h | 2 +- KernelLand/Kernel/include/timers.h | 5 +++++ KernelLand/Kernel/include/workqueue.h | 1 + KernelLand/Kernel/threads.c | 6 +++++- KernelLand/Kernel/time.c | 13 ++++++++++--- KernelLand/Kernel/workqueue.c | 13 +++++++++---- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/KernelLand/Kernel/include/acess.h b/KernelLand/Kernel/include/acess.h index 8a413a27..fe1a0f97 100644 --- a/KernelLand/Kernel/include/acess.h +++ b/KernelLand/Kernel/include/acess.h @@ -10,6 +10,7 @@ */ #include +#include #include #ifndef HALT_CPU @@ -51,7 +52,6 @@ typedef Uint32 tGID; //!< Group ID Type typedef Sint64 tTimestamp; //!< Timestamp (miliseconds since 00:00 1 Jan 1970) typedef Sint64 tTime; //!< Same again typedef struct sShortSpinlock tShortSpinlock; //!< Opaque (kinda) spinlock -typedef int bool; //!< Boolean type typedef Uint64 off_t; //!< VFS Offset typedef struct { char _[PAGE_SIZE];} tPage; // Representation of a page for pointer arithmatic diff --git a/KernelLand/Kernel/include/timers.h b/KernelLand/Kernel/include/timers.h index 24832986..e120060b 100644 --- a/KernelLand/Kernel/include/timers.h +++ b/KernelLand/Kernel/include/timers.h @@ -53,6 +53,11 @@ extern void Time_ScheduleTimer(tTimer *Timer, int Delta); */ extern void Time_RemoveTimer(tTimer *Timer); +/** + * Schedule a THREAD_EVENT_TIMER to fire in \a Delay milliseconds + */ +extern void Time_ScheduleEvent(int Delay); + /** * \brief Wait for a period of milliseconds */ diff --git a/KernelLand/Kernel/include/workqueue.h b/KernelLand/Kernel/include/workqueue.h index ff0c7f4c..1f5169aa 100644 --- a/KernelLand/Kernel/include/workqueue.h +++ b/KernelLand/Kernel/include/workqueue.h @@ -21,6 +21,7 @@ struct sWorkqueue void *Head; void *Tail; struct sThread *Sleeper; + struct sThread *SleepTail; }; extern void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset); diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index 73a2b58f..545896c4 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -783,9 +783,13 @@ int Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **L } *ListTail = us; } - else { + else if( ListHead ) { + us->Next = *ListHead; *ListHead = us; } + else { + // Nothing + } //if( Proc_ThreadSync(us) ) // return ; diff --git a/KernelLand/Kernel/time.c b/KernelLand/Kernel/time.c index a6ccd8be..15b61907 100644 --- a/KernelLand/Kernel/time.c +++ b/KernelLand/Kernel/time.c @@ -231,6 +231,14 @@ void Time_FreeTimer(tTimer *Timer) LOG("%p deallocated %p", __builtin_return_address(0), Timer); } +void Time_ScheduleEvent(int Delay) +{ + tTimer *t = &Proc_GetCurThread()->ThreadTimer; + Time_RemoveTimer(t); + Time_InitTimer(t, NULL, NULL); + Time_ScheduleTimer(t, Delay); +} + /** * \fn void Time_Delay(int Delay) * \brief Delay for a small ammount of time @@ -238,9 +246,8 @@ void Time_FreeTimer(tTimer *Timer) void Time_Delay(int Delay) { LOG("(%i)", Delay); - tTimer *t = &Proc_GetCurThread()->ThreadTimer; - Time_InitTimer(t, NULL, NULL); - Time_ScheduleTimer(t, Delay); + Threads_ClearEvent(THREAD_EVENT_TIMER); + Time_ScheduleEvent(Delay); Threads_WaitEvents(THREAD_EVENT_TIMER); } diff --git a/KernelLand/Kernel/workqueue.c b/KernelLand/Kernel/workqueue.c index 3e35b069..f5d78f80 100644 --- a/KernelLand/Kernel/workqueue.c +++ b/KernelLand/Kernel/workqueue.c @@ -16,6 +16,8 @@ void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset) { Queue->Name = Name; Queue->NextOffset = NextOfset; + Queue->Sleeper = NULL; + Queue->SleepTail = NULL; } void *Workqueue_GetWork(tWorkqueue *Queue) @@ -36,7 +38,7 @@ void *Workqueue_GetWork(tWorkqueue *Queue) Threads_int_Sleep(THREAD_STAT_QUEUESLEEP, Queue, 0, - &Queue->Sleeper, NULL, &Queue->Protector); + &Queue->Sleeper, &Queue->SleepTail, &Queue->Protector); } } @@ -53,9 +55,12 @@ void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr) if( Queue->Sleeper ) { - if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE ) - Threads_AddActive(Queue->Sleeper); - Queue->Sleeper = NULL; + ASSERTC( Queue->Sleeper->Status, !=, THREAD_STAT_ACTIVE ); + tThread *next_sleeper = Queue->Sleeper->Next; + Threads_AddActive(Queue->Sleeper); + Queue->Sleeper = next_sleeper; + if(!next_sleeper) + Queue->SleepTail = NULL; } SHORTREL(&Queue->Protector); } -- 2.20.1