From a2495c6ea4f4cab16b5d339ae511428e92e89e73 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 7 Feb 2012 16:38:04 +0800 Subject: [PATCH] Kernel - Slight reworks to timer code --- Kernel/include/acess.h | 25 ++-------- Kernel/include/events.h | 1 + Kernel/include/timers.h | 39 +++++++++++++++ Kernel/lib.c | 2 - Kernel/time.c | 90 +++++++++++++++++++++------------- Kernel/vfs/dir.c | 4 +- Modules/Storage/FDDv2/common.h | 3 +- Modules/Storage/FDDv2/fdc.c | 7 +-- Modules/USB/Core/main.c | 9 ++-- 9 files changed, 114 insertions(+), 66 deletions(-) create mode 100644 Kernel/include/timers.h diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index 1c645c25..2cd2cff1 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -471,30 +471,15 @@ extern int Module_LoadFile(const char *Path, const char *ArgStr); /** * \brief Create a timestamp from a time */ -extern Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year); +extern tTime timestamp(int sec, int mins, int hrs, int day, int month, int year); /** - * \brief Gets the current timestamp (miliseconds since Midnight 1st January 1970) - */ -extern Sint64 now(void); -/** - * \brief Timer callback function - */ -typedef void (tTimerCallback)(void *); -/** - * \brief Creates a one-shot timer - * \param Delta Period of the timer - * \param Callback Function to call each time - * \param Argument Argument to pass to the callback - */ -extern int Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument); -/** - * \brief Removed an active timer + * \brief Extract the date/time from a timestamp */ -extern void Time_RemoveTimer(int ID); +extern void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms); /** - * \brief Wait for a period of milliseconds + * \brief Gets the current timestamp (miliseconds since Midnight 1st January 1970) */ -extern void Time_Delay(int Delay); +extern Sint64 now(void); /** * \} */ diff --git a/Kernel/include/events.h b/Kernel/include/events.h index 9aa941d0..675c3dbc 100644 --- a/Kernel/include/events.h +++ b/Kernel/include/events.h @@ -13,6 +13,7 @@ #define THREAD_EVENT_VFS 0x00000001 #define THREAD_EVENT_IPCMSG 0x00000002 #define THREAD_EVENT_SIGNAL 0x00000004 +#define THREAD_EVENT_TIMER 0x00000008 // === FUNCTIONS === extern void Threads_PostEvent(tThread *Thread, Uint32 EventMask); diff --git a/Kernel/include/timers.h b/Kernel/include/timers.h new file mode 100644 index 00000000..22dd5c6a --- /dev/null +++ b/Kernel/include/timers.h @@ -0,0 +1,39 @@ +/* + * Acess2 Kernel + * - By John Hodge (thePowersGang) + * + * timers.h + * - Kernel timers + */ +#ifndef _KERNEL_TIMERS_H_ +#define _KERNEL_TIMERS_H_ +/** + * \file timers.h + * \brief Kernel timers + */ + +typedef struct sTimer tTimer; + +/** + * \brief Timer callback function + */ +typedef void (tTimerCallback)(void *); + +/** + * \brief Creates a one-shot timer + * \param Delta Period of the timer + * \param Callback Function to call each time + * \param Argument Argument to pass to the callback + */ +extern tTimer *Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument); +/** + * \brief Removed an active timer + */ +extern void Time_RemoveTimer(tTimer *Timer); +/** + * \brief Wait for a period of milliseconds + */ +extern void Time_Delay(int Delay); + +#endif + diff --git a/Kernel/lib.c b/Kernel/lib.c index 8612638c..60cbd4c7 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -39,9 +39,7 @@ char **str_split(const char *__str, char __ch); int WriteUTF8(Uint8 *str, Uint32 Val); int DivUp(int num, int dem); Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year); -#endif void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms); -#if 0 int rand(void); int CheckString(char *String); diff --git a/Kernel/time.c b/Kernel/time.c index de439472..2c83fa32 100644 --- a/Kernel/time.c +++ b/Kernel/time.c @@ -5,16 +5,20 @@ * Timer Code */ #include +#include +#include +#include // Proc_GetCurThread // === CONSTANTS === #define NUM_TIMERS 8 // === TYPEDEFS === -typedef struct sTimer { - int FiresAfter; +struct sTimer { + tTimer *Next; + Sint64 FiresAfter; void (*Callback)(void*); void *Argument; -} tTimer; +}; // === PROTOTYPES === void Timer_CallTimers(void); @@ -23,7 +27,7 @@ void Timer_CallTimers(void); volatile Uint64 giTicks = 0; volatile Sint64 giTimestamp = 0; volatile Uint64 giPartMiliseconds = 0; -tTimer gTimers[NUM_TIMERS]; // TODO: Replace by a ring-list timer +tTimer *gTimers; // TODO: Replace by a ring-list timer // === CODE === /** @@ -31,51 +35,65 @@ tTimer gTimers[NUM_TIMERS]; // TODO: Replace by a ring-list timer */ void Timer_CallTimers() { - int i; - void (*callback)(void *); - void *arg; - - for(i = 0; i < NUM_TIMERS; i ++) + while( gTimers && gTimers->FiresAfter < now() ) { - if(gTimers[i].Callback == NULL) continue; - if(giTimestamp < gTimers[i].FiresAfter) continue; - callback = gTimers[i].Callback; arg = gTimers[i].Argument; - gTimers[i].Callback = NULL; - callback(arg); + tTimer *next; + + if( gTimers->Callback ) + gTimers->Callback(gTimers->Argument); + else + Threads_PostEvent(gTimers->Argument, THREAD_EVENT_TIMER); + + next = gTimers->Next; + free(gTimers); + gTimers = next; } } /** - * \fn int Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument) + * \brief Schedule an action */ -int Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument) +tTimer *Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument) { - int ret; + tTimer *ret; + tTimer *t, *p; - if(Callback == NULL) return -1; + if(Callback == NULL) + Argument = Proc_GetCurThread(); + + // TODO: Use a pool instead? + ret = malloc(sizeof(tTimer)); - for(ret = 0; - ret < NUM_TIMERS; - ret++) + ret->Callback = Callback; + ret->FiresAfter = now() + Delta; + ret->Argument = Argument; + + // Add into list (sorted) + for( p = (tTimer*)&gTimers, t = gTimers; t; p = t, t = t->Next ) { - if(gTimers[ret].Callback != NULL) continue; - gTimers[ret].Callback = Callback; - gTimers[ret].FiresAfter = giTimestamp + Delta; - gTimers[ret].Argument = Argument; - //Log("Callback = %p", Callback); - //Log("Timer %i fires at %lli", ret, gTimers[ret].FiresAfter); - return ret; + if( t->FiresAfter > ret->FiresAfter ) break; } - return -1; + ret->Next = t; + p->Next = ret; + + return ret; } /** - * \fn void Time_RemoveTimer(int ID) + * \brief Delete a timer */ -void Time_RemoveTimer(int ID) +void Time_RemoveTimer(tTimer *Timer) { - if(ID < 0 || ID >= NUM_TIMERS) return; - gTimers[ID].Callback = NULL; + tTimer *t, *p; + for( p = (tTimer*)&gTimers, t = gTimers; t; p = t, t = t->Next ) + { + if( t == Timer ) + { + p->Next = t->Next; + free(Timer); + return ; + } + } } /** @@ -84,8 +102,10 @@ void Time_RemoveTimer(int ID) */ void Time_Delay(int Delay) { - tTime dest = now() + Delay; - while(dest > now()) Threads_Yield(); +// tTime dest = now() + Delay; +// while(dest > now()) Threads_Yield(); + Time_CreateTimer(Delay, NULL, NULL); + Threads_WaitEvents(THREAD_EVENT_TIMER); } // === EXPORTS === diff --git a/Kernel/vfs/dir.c b/Kernel/vfs/dir.c index aee7a603..d4c15309 100644 --- a/Kernel/vfs/dir.c +++ b/Kernel/vfs/dir.c @@ -13,9 +13,9 @@ extern tVFS_Mount *gRootMount; // === PROTOTYPES === #if 0 int VFS_MkDir(const char *Path); -#endif int VFS_MkNod(const char *Path, Uint Flags); -// int VFS_Symlink(const char *Name, const char *Link); + int VFS_Symlink(const char *Name, const char *Link); +#endif // === CODE === /** diff --git a/Modules/Storage/FDDv2/common.h b/Modules/Storage/FDDv2/common.h index f426716f..4d6a4f7e 100644 --- a/Modules/Storage/FDDv2/common.h +++ b/Modules/Storage/FDDv2/common.h @@ -9,6 +9,7 @@ #define _FDC_COMMON_H_ #include +#include // === CONSTANTS === #define MAX_DISKS 8 // 4 per controller, 2 controllers @@ -24,7 +25,7 @@ struct sFDD_Drive int bValid; int bInserted; int MotorState; - int Timer; + tTimer *Timer; tMutex Mutex; diff --git a/Modules/Storage/FDDv2/fdc.c b/Modules/Storage/FDDv2/fdc.c index d5711d92..e86b31c6 100644 --- a/Modules/Storage/FDDv2/fdc.c +++ b/Modules/Storage/FDDv2/fdc.c @@ -9,6 +9,7 @@ #include #include "common.h" #include +#include // === CONSTANTS === #define MOTOR_ON_DELAY 500 @@ -400,7 +401,7 @@ int FDD_int_StartMotor(int Disk) // Clear the motor off timer Time_RemoveTimer(gaFDD_Disks[Disk].Timer); - gaFDD_Disks[Disk].Timer = -1; + gaFDD_Disks[Disk].Timer = NULL; // Check if the motor is already on if( gaFDD_Disks[Disk].MotorState == MOTOR_ATSPEED ) @@ -424,7 +425,7 @@ int FDD_int_StopMotor(int Disk) { if( gaFDD_Disks[Disk].MotorState != MOTOR_ATSPEED ) return 0; - if( gaFDD_Disks[Disk].Timer != -1 ) + if( gaFDD_Disks[Disk].Timer != NULL ) return 0; gaFDD_Disks[Disk].Timer = Time_CreateTimer(MOTOR_OFF_DELAY, FDD_int_StopMotorCallback, (void*)(tVAddr)Disk); @@ -442,7 +443,7 @@ void FDD_int_StopMotorCallback(void *Ptr) int _disk; Uint16 base = FDD_int_GetBase(Disk, &_disk); - gaFDD_Disks[Disk].Timer = -1; + gaFDD_Disks[Disk].Timer = NULL; gaFDD_Disks[Disk].MotorState = MOTOR_OFF; outb(base + FDC_DOR, inb(base+FDC_DOR) & ~(1 << (_disk + 4))); diff --git a/Modules/USB/Core/main.c b/Modules/USB/Core/main.c index 36a1363b..df7f174f 100644 --- a/Modules/USB/Core/main.c +++ b/Modules/USB/Core/main.c @@ -23,14 +23,17 @@ tVFS_Node *USB_FindDir(tVFS_Node *Node, const char *Name); // === GLOBALS === MODULE_DEFINE(0, VERSION, USB_Core, USB_Install, NULL, NULL); +tVFS_NodeType gUSB_RootNodeType = { + .ReadDir = USB_ReadDir, + .FindDir = USB_FindDir, + .IOCtl = USB_IOCtl +}; tDevFS_Driver gUSB_DrvInfo = { NULL, "usb", { .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, .Flags = VFS_FFLAG_DIRECTORY, - .ReadDir = USB_ReadDir, - .FindDir = USB_FindDir, - .IOCtl = USB_IOCtl + .Type = &gUSB_RootNodeType } }; tUSBHost *gUSB_Hosts = NULL; -- 2.20.1