diff --git a/Makefile.in b/Makefile.in index 3b7a9c6..e0deb10 100644 --- a/Makefile.in +++ b/Makefile.in @@ -13,7 +13,7 @@ CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc" CC2NAME=gcc COPTIM=-O2 -CWARNS=-Wall -Wextra -Wshadow -Wpedantic +CWARNS=-Wall -Wextra -Wshadow // -Wpedantic CINCLUDES=-isystem./kaleid/include CFLAGS1=-std=gnu11 -nostdlib -ffreestanding -mcmodel=large diff --git a/boot/loader/io/ata.asm b/boot/loader/io/ata.asm index 9f6aaed..f075b7d 100644 --- a/boot/loader/io/ata.asm +++ b/boot/loader/io/ata.asm @@ -34,7 +34,7 @@ ;; GLOBAL DATA Bootdrv db 0 -end db "[End of Sector]", 0x0A, 0x0D, 0x0 +ended db "[End of Sector]", 0x0A, 0x0A, 0x0D, 0x0 buffer: times 513 db "_" ;; TEXT @@ -124,12 +124,19 @@ still_going: mov dx, 0x1f0 ; Data port - data comes in and out of here. rep insw pop rdi +%ifdef DEBUG mov bl, 0x0F mov esi, buffer call dump mov bl, 0x0A - mov esi, end + mov esi, ended call write + add qword [NextTRAM], 120 ; Cursor moving : 1120 = 80 * 2 * 7 lignes +%else + mov bl, 0x0A + mov esi, Pass + call write +%endif pop rdx pop rcx pop rbx diff --git a/boot/loader/io/lmterm.asm b/boot/loader/io/lmterm.asm index 3fa0ccb..427ae89 100644 --- a/boot/loader/io/lmterm.asm +++ b/boot/loader/io/lmterm.asm @@ -93,9 +93,9 @@ write: dump: ;-----------------------------------------------------------------------; -; x64/LM Dump Printing Functions ; +; x64/LM Dump 512 bytes of a buffer ; ; bl : color code ; -; esi : string address ; +; esi : buffer address ; ;-----------------------------------------------------------------------; mov edi, [NextTRAM] ; TRAM ADDRESS push rsi @@ -107,10 +107,9 @@ dump: stosb ; text subpixel mov al, bl stosb ; color subpixel - add qword [NextTRAM], 0x2 ; Cursor moving - add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels loop .pLoop pop rcx pop rdi pop rsi + add qword [NextTRAM], 1000 ; Cursor moving : 1120 = 80 * 2 * 7 lignes ret diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index a2bb849..c67f038 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -8,6 +8,8 @@ ; (x86_64 architecture only) ; ;=----------------------------------------------------------------------------=; +%define DEBUG + [BITS 16] [ORG 0x1000] @@ -92,13 +94,13 @@ main32: ;; VERIFY A20 pushad - mov edi,0x112345 ;odd megabyte address. - mov esi,0x012345 ;even megabyte address. - mov [esi],esi ;making sure that both addresses contain diffrent values. - mov [edi],edi ;(if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi)) - cmpsd ;compare addresses to see if the're equivalent. + mov edi,0x112345 ;odd megabyte address. + mov esi,0x012345 ;even megabyte address. + mov [esi],esi ;making sure that both addresses contain diffrent values. + mov [edi],edi ;(if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi)) + cmpsd ;compare addresses to see if the're equivalent. popad - jne .A20_on ;if not equivalent , A20 line is set. + jne .A20_on ;if not equivalent , A20 line is set. mov WORD [A20_OK], 0 jmp .A20_end .A20_on: @@ -161,18 +163,23 @@ main32: [BITS 64] ;; DATA -Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0 -CPUIDD db 0x09, " Checking CPUID...", 0 -EnA20 db 0x09, " Enabling A20 line...", 0 -ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D,0 -txt db 0x09, " Switching to Long Mode... ", 0 -Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0 -Pass db " OK", 0x0A, 0x0D, 0 -Fail db " FAIL!", 0x0A, 0x0D, 0 -msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0 -FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0 -DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0 -filename db "KERNEL BIN" + Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0 + CPUIDD db 0x09, " Checking CPUID...", 0 + EnA20 db 0x09, " Enabling A20 line...", 0 +%ifdef DEBUG + ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D, 0 +%else + ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0 +%endif + txt db 0x09, " Switching to Long Mode... ", 0 + EndOfLoader db "End of loader.bin. System will halt !", 0x0A, 0x0D, 0 + Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0 + Pass db " OK", 0x0A, 0x0D, 0 + Fail db " FAIL!", 0x0A, 0x0D, 0 + msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0 + FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0 + DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0 + filename db "KERNEL BIN" %include "boot/loader/io/lmmem.asm" %include "boot/loader/io/lmterm.asm" @@ -229,10 +236,10 @@ main64: mov bh, 1 call ata_read - call bitemporize ; Temporized because the ATA drive must be ready + mov bl, 0x0D + mov esi, EndOfLoader + call write jmp Die - ; times 1024 nop - ; XXX ; - ; It seems impossible to have an executable > 2.0 kB... +times 20 db 0 diff --git a/boot/mbr/mbr.asm b/boot/mbr/mbr.asm index 42f0dbd..f94c713 100644 --- a/boot/mbr/mbr.asm +++ b/boot/mbr/mbr.asm @@ -123,6 +123,7 @@ load_root: mov di, BUFFER_OFF ; Set es:di to the disk buffer mov cx, word [rootDirEntries] ; Search through all of the root dir entries xor ax, ax ; Clear ax for the file entry offset + search_root: xchg cx, dx ; Save cx because it's a loop counter mov si, filename ; Load the filename diff --git a/boot/mbr/mbr.inc b/boot/mbr/mbr.inc index dc11db1..a5f396d 100644 --- a/boot/mbr/mbr.inc +++ b/boot/mbr/mbr.inc @@ -101,7 +101,7 @@ read_sectors: shl ah, 1 or cl, ah ; Now cx is set with respective track and sector numbers mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h - mov di, 21 ; Try five times to read the sector because i love 21 + mov di, 21 ; Try five times to read the sector because I love 21 .attempt_read: mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector int 0x13 ; Call int 13h (BIOS disk I/O) diff --git a/build/bin/disk.img b/build/bin/disk.img index 9c35852..1dc81cd 100644 Binary files a/build/bin/disk.img and b/build/bin/disk.img differ diff --git a/build/bin/loader.bin b/build/bin/loader.bin index 94295b3..6ca87c7 100644 Binary files a/build/bin/loader.bin and b/build/bin/loader.bin differ diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index 94295b3..6ca87c7 100644 Binary files a/build/obj/boot/loader.bin and b/build/obj/boot/loader.bin differ diff --git a/kaleid/common/itoa.c b/kaleid/common/itoa.c index e24a41a..1144e26 100644 --- a/kaleid/common/itoa.c +++ b/kaleid/common/itoa.c @@ -10,59 +10,97 @@ #include // -// Digits table for bases <=36 +// Digits table for bases <=36 (unused) // +#if 0 static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +#endif + // // Integer to string in any base between 2 and 36 (included) // + #if defined(_NEED_ITOA) + +#define _IL_MIN INT_MIN +#define _IL_MIN_STRING "-2147483648" char *itoa(int i, char *str, int base) +{ + int rem; + #elif defined(_NEED_LTOA) + +#define _IL_MIN LONG_MIN +#define _IL_MIN_STRING "-9223372036854775808" char *ltoa(long i, char *str, int base) +{ + long rem; + #elif defined(_NEED_UTOA) + char *utoa(uint i, char *str, int base) +{ + uint rem; + #elif defined(_NEED_ULTOA) + char *ultoa(ulong i, char *str, int base) +{ + ulong rem; + #else #error "What am I supposed to declare?" #endif -{ -#if defined(_NEED_ITOA) || defined(_NEED_LTOA) - int neg = 0; -#endif - char *orig = str; - // - // Only handle base 2 -> 36 - // - if (base < 2 || base > 36) - return NULL; - #if defined(_NEED_ITOA) || defined(_NEED_LTOA) // // Deal with negatives // - if (i < 0) { - neg = 1; - i = -i; + int neg = 0; + if (i < 0 && base == 10) { + // + // Handle INT_MIN and LONG_MIN... + // + if (__builtin_expect(i == _IL_MIN, 0)) { + strcpy(orig, _IL_MIN_STRING); + goto leave; + } + + else { + neg = 1; + i = -i; + } } #endif + // + // Only handle base 2 -> 36 + // + if (base < 2 || base > 36) { + __set_errno(EINVAL); + *orig = '\0'; + goto leave; + } + // // Deal with zero separately // if (i == 0) { *str++ = '0'; + *str = '\0'; + goto leave; } // // Compute digits... in reverse order // while (i > 0) { - *str++ = digits[i % base]; + rem = i % base; + *str++ = (rem > 9) + ? (rem - 10) + 'a' + : rem + '0'; i /= base; } @@ -75,7 +113,13 @@ char *ultoa(ulong i, char *str, int base) // // Reverse the string // - return strrev2(orig); + orig = strrev2(orig); + + // + // End of conversion + // +leave: + return orig; } diff --git a/kaleid/common/memory.c b/kaleid/common/memory.c index 3497a38..20a9dd2 100644 --- a/kaleid/common/memory.c +++ b/kaleid/common/memory.c @@ -58,7 +58,7 @@ void *memset(void *ptr, int val, size_t bytes) } // -// Set "words"-many words starting from ptr to val +// Set "words"-many words starting from ptr to val // void *memsetw(void *ptr, int val, size_t words) { @@ -99,8 +99,8 @@ void *memsetw(void *ptr, int val, size_t words) } // -// Set "dwords"-many dwords starting from ptr to val -// XXX unimplemented +// Set "dwords"-many dwords starting from ptr to val +// XXX unimplemented // void *memsetd(void *ptr, int val, size_t dwords) { @@ -111,7 +111,7 @@ void *memsetd(void *ptr, int val, size_t dwords) } // -// Set "qwords"-many qwords starting from ptr to val +// Set "qwords"-many qwords starting from ptr to val // void *memsetq(void *ptr, long val, size_t qwords) { @@ -130,7 +130,7 @@ void *memsetq(void *ptr, long val, size_t qwords) //------------------------------------------// // -// Set "bytes"-many bytes starting from ptr to 0 +// Set "bytes"-many bytes starting from ptr to 0 // void *memzero(void *ptr, size_t bytes) { @@ -138,8 +138,8 @@ void *memzero(void *ptr, size_t bytes) } // -// Copy "bytes"-many bytes of src to dst -// Does not deal with overlapping blocks (memmove's job) +// Copy "bytes"-many bytes of src to dst +// Does not deal with overlapping blocks (memmove's job) // void *memcpy(void *restrict dst, const void *restrict src, size_t bytes) { @@ -203,7 +203,7 @@ void *memcpy(void *restrict dst, const void *restrict src, size_t bytes) } // -// Move memory from src to dest, even if they overlap +// Move memory from src to dest, even if they overlap // void *memmove(void *dst, const void *src, size_t bytes) { @@ -228,7 +228,7 @@ void *memmove(void *dst, const void *src, size_t bytes) } // -// Compare memory areas +// Compare memory areas // int memcmp(const void *ptr1, const void *ptr2, size_t bytes) { diff --git a/kaleid/common/rand.c b/kaleid/common/rand.c index fe576ef..41ca5d9 100644 --- a/kaleid/common/rand.c +++ b/kaleid/common/rand.c @@ -20,8 +20,8 @@ static ulong next = 7756; // int rand(void) { - next = next * 1103515245 + 12345; - return (uint)(next / 65536) % INT_MAX; + next = next * 1103515245 + 12347; + return (uint)(next / 65536); } // diff --git a/kaleid/common/sprintf.c b/kaleid/common/sprintf.c index a8dd3ba..fdd48dc 100644 --- a/kaleid/common/sprintf.c +++ b/kaleid/common/sprintf.c @@ -12,6 +12,9 @@ // // Format str according to fmt using ellipsed arguments // +// BE CAREFUL when using this +// you need to know for sure an overflow won't happen +// int sprintf(char *str, const char *fmt, ...) { int ret; @@ -31,6 +34,7 @@ int vsprintf(char *str, const char *fmt, va_list ap) // // (v)sprintf() but with a size limit: no more than n bytes are written in str +// Always null-terminate str // int snprintf(char *str, size_t n, const char *fmt, ...) { diff --git a/kaleid/common/string.c b/kaleid/common/string.c index fafaf89..dd1c210 100644 --- a/kaleid/common/string.c +++ b/kaleid/common/string.c @@ -235,7 +235,7 @@ char *strncpy(char *restrict dest, const char *restrict src, size_t n) // Returns TRUE if dest would have been null-terminated // by ordinary strncpy(), and FALSE otherwise // -int xstrncpy(char *restrict dest, const char *restrict src, size_t n) +int strnzcpy(char *restrict dest, const char *restrict src, size_t n) { size_t it; @@ -243,9 +243,7 @@ int xstrncpy(char *restrict dest, const char *restrict src, size_t n) dest[it] = src[it]; } - // // Was the copy complete? - // if (it == n) { if (dest[n] == 0) { return TRUE; @@ -261,11 +259,63 @@ int xstrncpy(char *restrict dest, const char *restrict src, size_t n) } // -// XXX strcat family +// Appends a copy of src at the end of dest // -char *strcat (char *restrict, const char *restrict); -char *strncat (char *restrict, const char *restrict, size_t); -int *xstrncat(char *restrict, const char *restrict, size_t); +char *strcat(char *restrict dest, const char *restrict src) +{ + char *base = dest; + while (*dest) dest++; + while ((*dest++ = *src++)); + return base; +} + +// +// Appends a copy of at most n bytes of src at the end of dest +// +char *strncat(char *restrict dest, const char *restrict src, size_t n) +{ + size_t it, off = 0; + + while (dest[off]) off++; + + for (it = 0; it < n && src[it]; it++) { + dest[it+off] = src[it]; + } + + while (it++ < n) dest[it+off] = 0; + + return dest; +} + +// +// Appends a copy of at most n bytes of src at the end of dest +// Always null-terminates, and returne TRUE or FALSE depending on whether +// regular strcat() would have null-terminated this string, or not +// +int strnzcat(char *restrict dest, const char *restrict src, size_t n) +{ + size_t it, off = 0; + + while (dest[off]) off++; + + for (it = 0; it < n - 1 && src[it]; it++) { + dest[it+off] = src[it]; + } + + // Was the copy complete? + if (it == n) { + if (dest[n+off] == 0) { + return TRUE; + } + + dest[n+off] = 0; + return FALSE; + } + + while (it++ < n) dest[it+off] = 0; + + return TRUE; +} // // Reverses the string src, putting the result into dest diff --git a/kaleid/include/common/kalcrt.h b/kaleid/include/common/kalcrt.h index 167ab52..8b9a43e 100644 --- a/kaleid/include/common/kalcrt.h +++ b/kaleid/include/common/kalcrt.h @@ -143,11 +143,11 @@ char *strtok_r(char *restrict, const char *restrict, char **restrict); char *strcpy (char *restrict, const char *restrict); char *strncpy (char *restrict, const char *restrict, size_t); -int xstrncpy(char *restrict, const char *restrict, size_t); +int strnzcpy(char *restrict, const char *restrict, size_t); char *strcat (char *restrict, const char *restrict); char *strncat (char *restrict, const char *restrict, size_t); -int *xstrncat(char *restrict, const char *restrict, size_t); +int strnzcat(char *restrict, const char *restrict, size_t); char *strrev(char *restrict, const char *restrict); char *strrev2(char *); diff --git a/kaleid/include/common/kaldefs.h b/kaleid/include/common/kaldefs.h index 9dbf1be..c2421d6 100644 --- a/kaleid/include/common/kaldefs.h +++ b/kaleid/include/common/kaldefs.h @@ -23,7 +23,7 @@ #endif #ifndef NULL -#define NULL ((void *)0) +#define NULL 0L #endif #ifndef INITOK @@ -61,8 +61,8 @@ // Attributes and macros // //------------------------------------------// -#ifndef PACKED -#define PACKED __attribute__((__packed__)) +#ifndef _PACKED +#define _PACKED __attribute__((__packed__)) #endif #ifndef noreturn @@ -77,6 +77,14 @@ #define unlikely(x) (__builtin_expect((x), 0)) #endif +#ifndef _STR +#define _STR(x) #x +#endif + +#ifndef _XSTR +#define _XSTR(x) _STR(x) +#endif + //------------------------------------------// // API specific macros // //------------------------------------------// diff --git a/kaleid/include/common/kalerror.h b/kaleid/include/common/kalerror.h index ce8b2c4..b29c660 100644 --- a/kaleid/include/common/kalerror.h +++ b/kaleid/include/common/kalerror.h @@ -11,7 +11,7 @@ #define _KALERROR_H //------------------------------------------// -// Preprocessor constants // +// "errno" values // //------------------------------------------// // Everything went fine diff --git a/kaleid/include/common/kallist.h b/kaleid/include/common/kallist.h index 96c5f9d..8257b64 100644 --- a/kaleid/include/common/kallist.h +++ b/kaleid/include/common/kallist.h @@ -204,7 +204,7 @@ static inline ListHead_t } // -// Remove node of list +// Remove node of list (and frees it) // static inline ListHead_t *RemoveNode(ListHead_t *head, ListNode_t *node) diff --git a/kaleid/include/common/kalmask.h b/kaleid/include/common/kalmask.h index 0295bd0..c185354 100644 --- a/kaleid/include/common/kalmask.h +++ b/kaleid/include/common/kalmask.h @@ -51,11 +51,11 @@ #define strcpy _osk_strcpy #define strncpy _osk_strncpy -#define xstrncpy _osk_xstrncpy +#define strnzcpy _osk_strnzcpy #define strcat _osk_strcat #define strncat _osk_strncat -#define xstrncat _osk_xstrncat +#define strnzcat _osk_strnzcat #define strrev _osk_strrev #define strrev2 _osk_strrev2 @@ -105,7 +105,7 @@ //------------------------------------------// -#define strerror _osk_strerror +#define strerror _osk_strerror //------------------------------------------// // End of header // diff --git a/kaleid/include/kalkern.h b/kaleid/include/kalkern.h index df15c7d..d1121eb 100644 --- a/kaleid/include/kalkern.h +++ b/kaleid/include/kalkern.h @@ -38,6 +38,13 @@ #include #endif +// not ready for kernel compilation +#ifndef _KALEID_KERNEL +#ifndef _KALKERN_SCHED_H +#include +#endif +#endif + //------------------------------------------// // End of header // //------------------------------------------// diff --git a/kaleid/include/kernel/kernbase.h b/kaleid/include/kernel/kernbase.h index baf8e95..ab2cb76 100644 --- a/kaleid/include/kernel/kernbase.h +++ b/kaleid/include/kernel/kernbase.h @@ -59,6 +59,10 @@ typedef enum { // Multiprocessor misc. // //------------------------------------------// +#ifndef INITOK +#define INITOK ((unsigned int)0xCAFEBABE) +#endif + #ifndef NCPU #define NCPU 4 #endif @@ -108,12 +112,6 @@ DECLARE_PER_CPU(CurThread, Thread_t *); // global constants // //------------------------------------------// -#define SetPanicStr(str) \ - do { \ - SetKernState(KSTATE_PANIC); \ - _SetPanicStr(str); \ - } while (0) - #define SetKernState(x) \ do { \ _SetKernState(x); \ @@ -184,7 +182,6 @@ void WriteByteOnPort(port_t port, port_t val) static inline uchar ReadByteFromPort(port_t port) { - KalAssert(FALSE && ENOSYS); (void)port; return 0; diff --git a/kaleid/include/kernel/kernlocks.h b/kaleid/include/kernel/kernlocks.h index f3dd7e2..6d32224 100644 --- a/kaleid/include/kernel/kernlocks.h +++ b/kaleid/include/kernel/kernlocks.h @@ -70,11 +70,15 @@ typedef struct sLock_t { //------------------------------------------// // -// Linux syscall... +// Linux syscall vs unimplemented syscall... // #ifndef _KALEID_KERNEL +#ifdef _OSK_SOURCE +int KalYieldCPU(void), +#else int sched_yield(void); #endif +#endif // // Initialize a lock @@ -127,7 +131,11 @@ void AquireLock(Lock_t *lock) StartPanic("AquireLock on an already locked object"); #else if likely (lock->type == KLOCK_SPINLOCK) continue; +#ifdef _OSK_SOURCE + else KalYieldCPU(); +#else else sched_yield(); +#endif #endif } __sync_synchronize(); diff --git a/kaleid/include/kernel/kernsched.h b/kaleid/include/kernel/kernsched.h index 1026d53..d99f8de 100644 --- a/kaleid/include/kernel/kernsched.h +++ b/kaleid/include/kernel/kernsched.h @@ -30,9 +30,10 @@ // Preprocessor // //------------------------------------------// +// +// Debug stuff +// #define printdbg printf -#define _STR(x) #x -#define _XSTR(x) _STR(x) // // States for a process @@ -56,6 +57,8 @@ DECLARE_PER_CPU(ReglPrioProcs, ListHead_t *); DECLARE_PER_CPU(ServPrioProcs, ListHead_t *); DECLARE_PER_CPU(TimeCritProcs, ListHead_t *); +extern const char *PrioClassesNames[]; + //------------------------------------------// // Data types // //------------------------------------------// @@ -63,7 +66,7 @@ DECLARE_PER_CPU(TimeCritProcs, ListHead_t *); // // A process // -typedef struct sProcess_t{ +typedef struct sProcess_t { // Identifier int pid; @@ -94,6 +97,16 @@ typedef struct sProcess_t{ } Process_t; +//------------------------------------------// +// Functions // +//------------------------------------------// + +void SchedInit(void); +void SchedFini(void); + +void SchedThisProc(Process_t *); +void SchedOnTick(void); + //------------------------------------------// // End of header // //------------------------------------------// diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c index 72fe089..79c9a89 100644 --- a/kaleid/kernel/ke/panic.c +++ b/kaleid/kernel/ke/panic.c @@ -34,6 +34,7 @@ noreturn void StartPanic(const char *str) { DisableIRQs(); + // This should be made atomic SetKernState(KSTATE_PANIC); if (GetCurProc()) __CurProc[GetCurCPU()] = NULL; @@ -46,11 +47,11 @@ noreturn void StartPanic(const char *str) } if (GetPanicStr()) { - GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "double panic!\n"); + GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nDouble panic!\n"); HaltCPU(); } - SetPanicStr(str); + _SetPanicStr(str); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - "); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str); diff --git a/kaleid/kernel/proc/Makefile b/kaleid/kernel/proc/Makefile index 8001a5e..7c15976 100644 --- a/kaleid/kernel/proc/Makefile +++ b/kaleid/kernel/proc/Makefile @@ -1,4 +1,4 @@ sched-test: - gcc -O2 -masm=intel -I../../include ./sched.c + gcc -O2 -Wall -Wextra -Wshadow -std=gnu11 -masm=intel -I../../include ./sched.c diff --git a/kaleid/kernel/proc/sched.c b/kaleid/kernel/proc/sched.c index b81ec45..2a8dd9e 100644 --- a/kaleid/kernel/proc/sched.c +++ b/kaleid/kernel/proc/sched.c @@ -7,7 +7,7 @@ // Desc: Scheduling algorithm // //----------------------------------------------------------------------------// -#include +#include #ifndef _KALEID_KERNEL @@ -17,17 +17,18 @@ CREATE_PER_CPU(CurProc, Process_t *); // // For test purpose only // -int procslen = 9; +int procslen = 10; Process_t procs[] = { { 0, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 1, 2, 2, 16, 16, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 2, 3, 3, 31, 31, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 3, 2, 2, 1, 1, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 4, 0, 0, 5, 5, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, + { 4, 3, 3, 5, 5, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 5, 0, 0, 30, 30, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 6, 1, 1, 19, 19, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 7, 1, 1, 0, 0, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 8, 3, 3, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, + { 9, 2, 2, 21, 21, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, }; #endif @@ -66,22 +67,23 @@ void SchedUnlock(void) { // // The four priority classes of OS/2 // -CREATE_PER_CPU(IdlePrioProcs, ListHead_t *); -CREATE_PER_CPU(ReglPrioProcs, ListHead_t *); -CREATE_PER_CPU(ServPrioProcs, ListHead_t *); -CREATE_PER_CPU(TimeCritProcs, ListHead_t *); -char *PrioClassesNames[] = { - "Idle priority class", - "Regular priority class", - "Server priority class", +CREATE_PER_CPU(TimeCritProcs, ListHead_t *); +CREATE_PER_CPU(ServPrioProcs, ListHead_t *); +CREATE_PER_CPU(ReglPrioProcs, ListHead_t *); +CREATE_PER_CPU(IdlePrioProcs, ListHead_t *); + +const char *PrioClassesNames[] = { "Time-critical class", + "Server priority class", + "Regular priority class", + "Idle priority class", }; -enum { IDLE_PRIO_PROC = 0, - REGL_PRIO_PROC = 1, - SERV_PRIO_PROC = 2, - TIME_CRIT_PROC = 3, +enum { TIME_CRIT_PROC = 0, + SERV_PRIO_PROC = 1, + REGL_PRIO_PROC = 2, + IDLE_PRIO_PROC = 3, }; // @@ -110,8 +112,8 @@ Process_t *CompareProcs(Process_t *proc1, Process_t *proc2) { KalAssert(proc1 && proc2); - if (proc1->prioClass > proc2->prioClass) return proc1; - if (proc1->prioClass < proc2->prioClass) return proc2; + if (proc1->prioClass < proc2->prioClass) return proc1; + if (proc1->prioClass > proc2->prioClass) return proc2; if (proc1->prioLevel > proc2->prioLevel) return proc1; if (proc1->prioLevel < proc2->prioLevel) return proc2; @@ -125,7 +127,7 @@ Process_t *CompareProcs(Process_t *proc1, Process_t *proc2) static inline void SchedThisProcUnlocked(Process_t *proc) { - KalAssert(proc && proc->procState == STATE_RUNNABLE); + KalAssert(proc && proc->procState == STATE_RUNNABLE && !proc->schedNode); bool found = false; ListNode_t *iterNode = NULL; @@ -136,13 +138,15 @@ void SchedThisProcUnlocked(Process_t *proc) proc->schedNode = procNode; - //printdbg("Adding process %d to '%s'\n", proc->pid, PrioClassesNames[proc->prioClass]); - // // Find a process with lesser priority // for (iterNode = head->first; iterNode; iterNode = iterNode->next) { if (proc->prioLevel > GetNodeData(iterNode, Process_t *)->prioLevel) { + // Detect double insertions + KalAssert(proc->pid != GetNodeData(iterNode, Process_t *)->pid); + + // Add process to schedule AddNodeBefore(head, iterNode, procNode); found = true; break; @@ -197,53 +201,65 @@ void BlockCurProc(void) ListNode_t *procNode = GetCurProc()->schedNode; + KalAssert(procNode && "Blocking non-scheduled process"); + GetCurProc()->procState = STATE_BLOCKED; RemoveNode(procNode->head, procNode); + GetCurProc()->schedNode = NULL; SetCurProc(SelectSchedNext()); } +static inline +void ReSchedCurProc(void) +{ + KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING); + KalAssert(GetCurProc()->schedNode); + + // Restore default attributes, cancelling boosts + GetCurProc()->prioClass = GetCurProc()->defPrioClass; + GetCurProc()->prioLevel = GetCurProc()->defPrioLevel; + GetCurProc()->timeSlice = GetCurProc()->defTimeSlice; + GetCurProc()->procState = STATE_RUNNABLE; + + // Remove from list + RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode); + GetCurProc()->schedNode = NULL; + + // Schedule again, with default attributes now + SchedThisProcUnlocked(GetCurProc()); +} + // // Should we schedule another process? // Called at each tick // void SchedOnTick(void) { - Process_t *procNext; - Process_t *winner; - SchedLock(); + Process_t *procNext, *winner, *previous = GetCurProc(); + // // We're either idle or running something // KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING); // - // Has current process spent his timeslice? + // Have the current process spent its timeslice? // (To be handled in CPU decisions function) // if (GetCurProc() != NULL) { if (GetCurProc()->timeSlice <= 1) { + // Re-schedule + ReSchedCurProc(); - // Restore default attributes, cancelling boosts - GetCurProc()->prioClass = GetCurProc()->defPrioClass; - GetCurProc()->prioLevel = GetCurProc()->defPrioLevel; - GetCurProc()->timeSlice = GetCurProc()->defTimeSlice; - GetCurProc()->procState = STATE_RUNNABLE; - - // Remove from list - RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode); - - // Schedule again, with default attributes now - SchedThisProcUnlocked(GetCurProc()); - - // Mark as idle - SetCurProc(NULL); + // See next 'if' statement + _SetCurProc(NULL); } // - // Otherwise, make him lose a tick + // Otherwise, make it lose a tick // else { GetCurProc()->timeSlice--; @@ -268,8 +284,10 @@ void SchedOnTick(void) // Yes, procNext should preempt current process // if (winner == procNext) { - GetCurProc()->procState = STATE_RUNNABLE; - SchedThisProcUnlocked(GetCurProc()); + // Re-schedule + ReSchedCurProc(); + + // Switch to procNext SetCurProc(procNext); } @@ -278,32 +296,10 @@ void SchedOnTick(void) // leave: SchedUnlock(); -} -#define PrintProc(proc) printdbg("{ %d, '%s', %d , %d}\n", (proc)->pid, \ - PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice); - -// -// Print out process list -// -void PrintList(ListHead_t *head) -{ - KalAssert(head); - - Process_t *proc; - ListNode_t *node = head->first; - - printdbg("len: %d\n", head->length); - - while (node) { - proc = GetNodeData(node, Process_t *); - - PrintProc(proc); - - node = node->next; + if (GetCurProc() != NULL && GetCurProc() != previous) { + // XXX context switch } - - puts(""); } // @@ -312,7 +308,6 @@ void PrintList(ListHead_t *head) void InitSched(void) { int pid; - Process_t *proc; SchedLock(); @@ -355,6 +350,33 @@ void FiniSched(void) } #ifndef _KALEID_KERNEL + +#define PrintProc(proc) printdbg("{ %d, '%s', %d , %lu}\n", (proc)->pid, \ + PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice); + +// +// Print out process list +// +void PrintList(ListHead_t *head) +{ + KalAssert(head); + + Process_t *proc; + ListNode_t *node = head->first; + + printdbg("len: %lu\n", head->length); + + while (node) { + proc = GetNodeData(node, Process_t *); + + PrintProc(proc); + + node = node->next; + } + + puts(""); +} + int main(void) { InitSched(); @@ -379,7 +401,17 @@ int main(void) int tick = 0; - while (tick < 20) { + while (tick < 120) { + if (tick > 0 && tick != 50 && tick % 10 == 0) { + puts("Blocking current process"); + BlockCurProc(); + } + + if (tick == 50) { + procs[0].procState = STATE_RUNNABLE; + SchedThisProc(&procs[0]); + } + printf("Tick %d - Running: ", tick); if (GetCurProc() == NULL) { @@ -390,14 +422,11 @@ int main(void) PrintProc(GetCurProc()); } - if (tick == 9 || tick == 14) { - puts("Blocking current process"); - BlockCurProc(); - } - SchedOnTick(); - //puts("\n---------------"); + if (tick == 50) // already done + puts("Re-scheduling process 0"); + tick++; } @@ -405,5 +434,6 @@ int main(void) return 0; } + #endif