commit
7aefcf6784
|
@ -13,7 +13,7 @@
|
||||||
CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc"
|
CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc"
|
||||||
CC2NAME=gcc
|
CC2NAME=gcc
|
||||||
COPTIM=-O2
|
COPTIM=-O2
|
||||||
CWARNS=-Wall -Wextra -Wshadow -Wpedantic
|
CWARNS=-Wall -Wextra -Wshadow // -Wpedantic
|
||||||
CINCLUDES=-isystem./kaleid/include
|
CINCLUDES=-isystem./kaleid/include
|
||||||
|
|
||||||
CFLAGS1=-std=gnu11 -nostdlib -ffreestanding -mcmodel=large
|
CFLAGS1=-std=gnu11 -nostdlib -ffreestanding -mcmodel=large
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
;; GLOBAL DATA
|
;; GLOBAL DATA
|
||||||
|
|
||||||
Bootdrv db 0
|
Bootdrv db 0
|
||||||
end db "[End of Sector]", 0x0A, 0x0D, 0x0
|
ended db "[End of Sector]", 0x0A, 0x0A, 0x0D, 0x0
|
||||||
buffer: times 513 db "_"
|
buffer: times 513 db "_"
|
||||||
|
|
||||||
;; TEXT
|
;; TEXT
|
||||||
|
@ -124,12 +124,19 @@ still_going:
|
||||||
mov dx, 0x1f0 ; Data port - data comes in and out of here.
|
mov dx, 0x1f0 ; Data port - data comes in and out of here.
|
||||||
rep insw
|
rep insw
|
||||||
pop rdi
|
pop rdi
|
||||||
|
%ifdef DEBUG
|
||||||
mov bl, 0x0F
|
mov bl, 0x0F
|
||||||
mov esi, buffer
|
mov esi, buffer
|
||||||
call dump
|
call dump
|
||||||
mov bl, 0x0A
|
mov bl, 0x0A
|
||||||
mov esi, end
|
mov esi, ended
|
||||||
call write
|
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 rdx
|
||||||
pop rcx
|
pop rcx
|
||||||
pop rbx
|
pop rbx
|
||||||
|
|
|
@ -93,9 +93,9 @@ write:
|
||||||
|
|
||||||
dump:
|
dump:
|
||||||
;-----------------------------------------------------------------------;
|
;-----------------------------------------------------------------------;
|
||||||
; x64/LM Dump Printing Functions ;
|
; x64/LM Dump 512 bytes of a buffer ;
|
||||||
; bl : color code ;
|
; bl : color code ;
|
||||||
; esi : string address ;
|
; esi : buffer address ;
|
||||||
;-----------------------------------------------------------------------;
|
;-----------------------------------------------------------------------;
|
||||||
mov edi, [NextTRAM] ; TRAM ADDRESS
|
mov edi, [NextTRAM] ; TRAM ADDRESS
|
||||||
push rsi
|
push rsi
|
||||||
|
@ -107,10 +107,9 @@ dump:
|
||||||
stosb ; text subpixel
|
stosb ; text subpixel
|
||||||
mov al, bl
|
mov al, bl
|
||||||
stosb ; color subpixel
|
stosb ; color subpixel
|
||||||
add qword [NextTRAM], 0x2 ; Cursor moving
|
|
||||||
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
|
|
||||||
loop .pLoop
|
loop .pLoop
|
||||||
pop rcx
|
pop rcx
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rsi
|
pop rsi
|
||||||
|
add qword [NextTRAM], 1000 ; Cursor moving : 1120 = 80 * 2 * 7 lignes
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
; (x86_64 architecture only) ;
|
; (x86_64 architecture only) ;
|
||||||
;=----------------------------------------------------------------------------=;
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
%define DEBUG
|
||||||
|
|
||||||
[BITS 16]
|
[BITS 16]
|
||||||
[ORG 0x1000]
|
[ORG 0x1000]
|
||||||
|
|
||||||
|
@ -161,18 +163,23 @@ main32:
|
||||||
[BITS 64]
|
[BITS 64]
|
||||||
|
|
||||||
;; DATA
|
;; DATA
|
||||||
Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0
|
Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0
|
||||||
CPUIDD db 0x09, " Checking CPUID...", 0
|
CPUIDD db 0x09, " Checking CPUID...", 0
|
||||||
EnA20 db 0x09, " Enabling A20 line...", 0
|
EnA20 db 0x09, " Enabling A20 line...", 0
|
||||||
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D,0
|
%ifdef DEBUG
|
||||||
txt db 0x09, " Switching to Long Mode... ", 0
|
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D, 0
|
||||||
Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0
|
%else
|
||||||
Pass db " OK", 0x0A, 0x0D, 0
|
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0
|
||||||
Fail db " FAIL!", 0x0A, 0x0D, 0
|
%endif
|
||||||
msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0
|
txt db 0x09, " Switching to Long Mode... ", 0
|
||||||
FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0
|
EndOfLoader db "End of loader.bin. System will halt !", 0x0A, 0x0D, 0
|
||||||
DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0
|
Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0
|
||||||
filename db "KERNEL BIN"
|
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/lmmem.asm"
|
||||||
%include "boot/loader/io/lmterm.asm"
|
%include "boot/loader/io/lmterm.asm"
|
||||||
|
@ -229,10 +236,10 @@ main64:
|
||||||
mov bh, 1
|
mov bh, 1
|
||||||
call ata_read
|
call ata_read
|
||||||
|
|
||||||
call bitemporize ; Temporized because the ATA drive must be ready
|
mov bl, 0x0D
|
||||||
|
mov esi, EndOfLoader
|
||||||
|
call write
|
||||||
|
|
||||||
jmp Die
|
jmp Die
|
||||||
|
|
||||||
; times 1024 nop
|
times 20 db 0
|
||||||
; XXX ;
|
|
||||||
; It seems impossible to have an executable > 2.0 kB...
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ load_root:
|
||||||
mov di, BUFFER_OFF ; Set es:di to the disk buffer
|
mov di, BUFFER_OFF ; Set es:di to the disk buffer
|
||||||
mov cx, word [rootDirEntries] ; Search through all of the root dir entries
|
mov cx, word [rootDirEntries] ; Search through all of the root dir entries
|
||||||
xor ax, ax ; Clear ax for the file entry offset
|
xor ax, ax ; Clear ax for the file entry offset
|
||||||
|
|
||||||
search_root:
|
search_root:
|
||||||
xchg cx, dx ; Save cx because it's a loop counter
|
xchg cx, dx ; Save cx because it's a loop counter
|
||||||
mov si, filename ; Load the filename
|
mov si, filename ; Load the filename
|
||||||
|
|
|
@ -101,7 +101,7 @@ read_sectors:
|
||||||
shl ah, 1
|
shl ah, 1
|
||||||
or cl, ah ; Now cx is set with respective track and sector numbers
|
or cl, ah ; Now cx is set with respective track and sector numbers
|
||||||
mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h
|
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:
|
.attempt_read:
|
||||||
mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector
|
mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector
|
||||||
int 0x13 ; Call int 13h (BIOS disk I/O)
|
int 0x13 ; Call int 13h (BIOS disk I/O)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -10,59 +10,97 @@
|
||||||
#include <kaleid.h>
|
#include <kaleid.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Digits table for bases <=36
|
// Digits table for bases <=36 (unused)
|
||||||
//
|
//
|
||||||
|
#if 0
|
||||||
static const char digits[] =
|
static const char digits[] =
|
||||||
"0123456789abcdefghijklmnopqrstuvwxyz";
|
"0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Integer to string in any base between 2 and 36 (included)
|
// Integer to string in any base between 2 and 36 (included)
|
||||||
//
|
//
|
||||||
|
|
||||||
#if defined(_NEED_ITOA)
|
#if defined(_NEED_ITOA)
|
||||||
|
|
||||||
|
#define _IL_MIN INT_MIN
|
||||||
|
#define _IL_MIN_STRING "-2147483648"
|
||||||
char *itoa(int i, char *str, int base)
|
char *itoa(int i, char *str, int base)
|
||||||
|
{
|
||||||
|
int rem;
|
||||||
|
|
||||||
#elif defined(_NEED_LTOA)
|
#elif defined(_NEED_LTOA)
|
||||||
|
|
||||||
|
#define _IL_MIN LONG_MIN
|
||||||
|
#define _IL_MIN_STRING "-9223372036854775808"
|
||||||
char *ltoa(long i, char *str, int base)
|
char *ltoa(long i, char *str, int base)
|
||||||
|
{
|
||||||
|
long rem;
|
||||||
|
|
||||||
#elif defined(_NEED_UTOA)
|
#elif defined(_NEED_UTOA)
|
||||||
|
|
||||||
char *utoa(uint i, char *str, int base)
|
char *utoa(uint i, char *str, int base)
|
||||||
|
{
|
||||||
|
uint rem;
|
||||||
|
|
||||||
#elif defined(_NEED_ULTOA)
|
#elif defined(_NEED_ULTOA)
|
||||||
|
|
||||||
char *ultoa(ulong i, char *str, int base)
|
char *ultoa(ulong i, char *str, int base)
|
||||||
|
{
|
||||||
|
ulong rem;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "What am I supposed to declare?"
|
#error "What am I supposed to declare?"
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
|
||||||
int neg = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *orig = str;
|
char *orig = str;
|
||||||
|
|
||||||
//
|
|
||||||
// Only handle base 2 -> 36
|
|
||||||
//
|
|
||||||
if (base < 2 || base > 36)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
||||||
//
|
//
|
||||||
// Deal with negatives
|
// Deal with negatives
|
||||||
//
|
//
|
||||||
if (i < 0) {
|
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;
|
neg = 1;
|
||||||
i = -i;
|
i = -i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only handle base 2 -> 36
|
||||||
|
//
|
||||||
|
if (base < 2 || base > 36) {
|
||||||
|
__set_errno(EINVAL);
|
||||||
|
*orig = '\0';
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Deal with zero separately
|
// Deal with zero separately
|
||||||
//
|
//
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
*str++ = '0';
|
*str++ = '0';
|
||||||
|
*str = '\0';
|
||||||
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compute digits... in reverse order
|
// Compute digits... in reverse order
|
||||||
//
|
//
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
*str++ = digits[i % base];
|
rem = i % base;
|
||||||
|
*str++ = (rem > 9)
|
||||||
|
? (rem - 10) + 'a'
|
||||||
|
: rem + '0';
|
||||||
i /= base;
|
i /= base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +113,13 @@ char *ultoa(ulong i, char *str, int base)
|
||||||
//
|
//
|
||||||
// Reverse the string
|
// Reverse the string
|
||||||
//
|
//
|
||||||
return strrev2(orig);
|
orig = strrev2(orig);
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of conversion
|
||||||
|
//
|
||||||
|
leave:
|
||||||
|
return orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ static ulong next = 7756;
|
||||||
//
|
//
|
||||||
int rand(void)
|
int rand(void)
|
||||||
{
|
{
|
||||||
next = next * 1103515245 + 12345;
|
next = next * 1103515245 + 12347;
|
||||||
return (uint)(next / 65536) % INT_MAX;
|
return (uint)(next / 65536);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
//
|
//
|
||||||
// Format str according to fmt using ellipsed arguments
|
// 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 sprintf(char *str, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
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
|
// (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, ...)
|
int snprintf(char *str, size_t n, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
// Returns TRUE if dest would have been null-terminated
|
||||||
// by ordinary strncpy(), and FALSE otherwise
|
// 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;
|
size_t it;
|
||||||
|
|
||||||
|
@ -243,9 +243,7 @@ int xstrncpy(char *restrict dest, const char *restrict src, size_t n)
|
||||||
dest[it] = src[it];
|
dest[it] = src[it];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Was the copy complete?
|
// Was the copy complete?
|
||||||
//
|
|
||||||
if (it == n) {
|
if (it == n) {
|
||||||
if (dest[n] == 0) {
|
if (dest[n] == 0) {
|
||||||
return TRUE;
|
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 *strcat(char *restrict dest, const char *restrict src)
|
||||||
char *strncat (char *restrict, const char *restrict, size_t);
|
{
|
||||||
int *xstrncat(char *restrict, const char *restrict, size_t);
|
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
|
// Reverses the string src, putting the result into dest
|
||||||
|
|
|
@ -143,11 +143,11 @@ char *strtok_r(char *restrict, const char *restrict, char **restrict);
|
||||||
|
|
||||||
char *strcpy (char *restrict, const char *restrict);
|
char *strcpy (char *restrict, const char *restrict);
|
||||||
char *strncpy (char *restrict, const char *restrict, size_t);
|
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 *strcat (char *restrict, const char *restrict);
|
||||||
char *strncat (char *restrict, const char *restrict, size_t);
|
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 *strrev(char *restrict, const char *restrict);
|
||||||
char *strrev2(char *);
|
char *strrev2(char *);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL ((void *)0)
|
#define NULL 0L
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INITOK
|
#ifndef INITOK
|
||||||
|
@ -61,8 +61,8 @@
|
||||||
// Attributes and macros //
|
// Attributes and macros //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
#ifndef PACKED
|
#ifndef _PACKED
|
||||||
#define PACKED __attribute__((__packed__))
|
#define _PACKED __attribute__((__packed__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef noreturn
|
#ifndef noreturn
|
||||||
|
@ -77,6 +77,14 @@
|
||||||
#define unlikely(x) (__builtin_expect((x), 0))
|
#define unlikely(x) (__builtin_expect((x), 0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _STR
|
||||||
|
#define _STR(x) #x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _XSTR
|
||||||
|
#define _XSTR(x) _STR(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// API specific macros //
|
// API specific macros //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define _KALERROR_H
|
#define _KALERROR_H
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// Preprocessor constants //
|
// "errno" values //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
// Everything went fine
|
// Everything went fine
|
||||||
|
|
|
@ -204,7 +204,7 @@ static inline ListHead_t
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remove node of list
|
// Remove node of list (and frees it)
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*RemoveNode(ListHead_t *head, ListNode_t *node)
|
*RemoveNode(ListHead_t *head, ListNode_t *node)
|
||||||
|
|
|
@ -51,11 +51,11 @@
|
||||||
|
|
||||||
#define strcpy _osk_strcpy
|
#define strcpy _osk_strcpy
|
||||||
#define strncpy _osk_strncpy
|
#define strncpy _osk_strncpy
|
||||||
#define xstrncpy _osk_xstrncpy
|
#define strnzcpy _osk_strnzcpy
|
||||||
|
|
||||||
#define strcat _osk_strcat
|
#define strcat _osk_strcat
|
||||||
#define strncat _osk_strncat
|
#define strncat _osk_strncat
|
||||||
#define xstrncat _osk_xstrncat
|
#define strnzcat _osk_strnzcat
|
||||||
|
|
||||||
#define strrev _osk_strrev
|
#define strrev _osk_strrev
|
||||||
#define strrev2 _osk_strrev2
|
#define strrev2 _osk_strrev2
|
||||||
|
|
|
@ -38,6 +38,13 @@
|
||||||
#include <kernel/kernterm.h>
|
#include <kernel/kernterm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// not ready for kernel compilation
|
||||||
|
#ifndef _KALEID_KERNEL
|
||||||
|
#ifndef _KALKERN_SCHED_H
|
||||||
|
#include <kernel/kernsched.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// End of header //
|
// End of header //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
|
@ -59,6 +59,10 @@ typedef enum {
|
||||||
// Multiprocessor misc. //
|
// Multiprocessor misc. //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef INITOK
|
||||||
|
#define INITOK ((unsigned int)0xCAFEBABE)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NCPU
|
#ifndef NCPU
|
||||||
#define NCPU 4
|
#define NCPU 4
|
||||||
#endif
|
#endif
|
||||||
|
@ -108,12 +112,6 @@ DECLARE_PER_CPU(CurThread, Thread_t *);
|
||||||
// global constants //
|
// global constants //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
#define SetPanicStr(str) \
|
|
||||||
do { \
|
|
||||||
SetKernState(KSTATE_PANIC); \
|
|
||||||
_SetPanicStr(str); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SetKernState(x) \
|
#define SetKernState(x) \
|
||||||
do { \
|
do { \
|
||||||
_SetKernState(x); \
|
_SetKernState(x); \
|
||||||
|
@ -184,7 +182,6 @@ void WriteByteOnPort(port_t port, port_t val)
|
||||||
static inline
|
static inline
|
||||||
uchar ReadByteFromPort(port_t port)
|
uchar ReadByteFromPort(port_t port)
|
||||||
{
|
{
|
||||||
|
|
||||||
KalAssert(FALSE && ENOSYS);
|
KalAssert(FALSE && ENOSYS);
|
||||||
(void)port;
|
(void)port;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -70,11 +70,15 @@ typedef struct sLock_t {
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Linux syscall...
|
// Linux syscall vs unimplemented syscall...
|
||||||
//
|
//
|
||||||
#ifndef _KALEID_KERNEL
|
#ifndef _KALEID_KERNEL
|
||||||
|
#ifdef _OSK_SOURCE
|
||||||
|
int KalYieldCPU(void),
|
||||||
|
#else
|
||||||
int sched_yield(void);
|
int sched_yield(void);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize a lock
|
// Initialize a lock
|
||||||
|
@ -127,7 +131,11 @@ void AquireLock(Lock_t *lock)
|
||||||
StartPanic("AquireLock on an already locked object");
|
StartPanic("AquireLock on an already locked object");
|
||||||
#else
|
#else
|
||||||
if likely (lock->type == KLOCK_SPINLOCK) continue;
|
if likely (lock->type == KLOCK_SPINLOCK) continue;
|
||||||
|
#ifdef _OSK_SOURCE
|
||||||
|
else KalYieldCPU();
|
||||||
|
#else
|
||||||
else sched_yield();
|
else sched_yield();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
|
|
|
@ -30,9 +30,10 @@
|
||||||
// Preprocessor //
|
// Preprocessor //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debug stuff
|
||||||
|
//
|
||||||
#define printdbg printf
|
#define printdbg printf
|
||||||
#define _STR(x) #x
|
|
||||||
#define _XSTR(x) _STR(x)
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// States for a process
|
// States for a process
|
||||||
|
@ -56,6 +57,8 @@ DECLARE_PER_CPU(ReglPrioProcs, ListHead_t *);
|
||||||
DECLARE_PER_CPU(ServPrioProcs, ListHead_t *);
|
DECLARE_PER_CPU(ServPrioProcs, ListHead_t *);
|
||||||
DECLARE_PER_CPU(TimeCritProcs, ListHead_t *);
|
DECLARE_PER_CPU(TimeCritProcs, ListHead_t *);
|
||||||
|
|
||||||
|
extern const char *PrioClassesNames[];
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// Data types //
|
// Data types //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
@ -63,7 +66,7 @@ DECLARE_PER_CPU(TimeCritProcs, ListHead_t *);
|
||||||
//
|
//
|
||||||
// A process
|
// A process
|
||||||
//
|
//
|
||||||
typedef struct sProcess_t{
|
typedef struct sProcess_t {
|
||||||
|
|
||||||
// Identifier
|
// Identifier
|
||||||
int pid;
|
int pid;
|
||||||
|
@ -94,6 +97,16 @@ typedef struct sProcess_t{
|
||||||
|
|
||||||
} Process_t;
|
} Process_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
void SchedInit(void);
|
||||||
|
void SchedFini(void);
|
||||||
|
|
||||||
|
void SchedThisProc(Process_t *);
|
||||||
|
void SchedOnTick(void);
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// End of header //
|
// End of header //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
|
@ -34,6 +34,7 @@ noreturn void StartPanic(const char *str)
|
||||||
{
|
{
|
||||||
DisableIRQs();
|
DisableIRQs();
|
||||||
|
|
||||||
|
// This should be made atomic
|
||||||
SetKernState(KSTATE_PANIC);
|
SetKernState(KSTATE_PANIC);
|
||||||
|
|
||||||
if (GetCurProc()) __CurProc[GetCurCPU()] = NULL;
|
if (GetCurProc()) __CurProc[GetCurCPU()] = NULL;
|
||||||
|
@ -46,11 +47,11 @@ noreturn void StartPanic(const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetPanicStr()) {
|
if (GetPanicStr()) {
|
||||||
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "double panic!\n");
|
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nDouble panic!\n");
|
||||||
HaltCPU();
|
HaltCPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPanicStr(str);
|
_SetPanicStr(str);
|
||||||
|
|
||||||
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - ");
|
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - ");
|
||||||
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str);
|
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
sched-test:
|
sched-test:
|
||||||
gcc -O2 -masm=intel -I../../include ./sched.c
|
gcc -O2 -Wall -Wextra -Wshadow -std=gnu11 -masm=intel -I../../include ./sched.c
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// Desc: Scheduling algorithm //
|
// Desc: Scheduling algorithm //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include <kernel/kernsched.h>
|
#include <kalkern.h>
|
||||||
|
|
||||||
#ifndef _KALEID_KERNEL
|
#ifndef _KALEID_KERNEL
|
||||||
|
|
||||||
|
@ -17,17 +17,18 @@ CREATE_PER_CPU(CurProc, Process_t *);
|
||||||
//
|
//
|
||||||
// For test purpose only
|
// For test purpose only
|
||||||
//
|
//
|
||||||
int procslen = 9;
|
int procslen = 10;
|
||||||
Process_t procs[] = {
|
Process_t procs[] = {
|
||||||
{ 0, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
|
{ 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 },
|
{ 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 },
|
{ 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 },
|
{ 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 },
|
{ 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 },
|
{ 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 },
|
{ 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 },
|
{ 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
|
#endif
|
||||||
|
@ -66,22 +67,23 @@ void SchedUnlock(void) {
|
||||||
//
|
//
|
||||||
// The four priority classes of OS/2
|
// 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[] = {
|
CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
|
||||||
"Idle priority class",
|
CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
|
||||||
"Regular priority class",
|
CREATE_PER_CPU(ReglPrioProcs, ListHead_t *);
|
||||||
"Server priority class",
|
CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);
|
||||||
|
|
||||||
|
const char *PrioClassesNames[] = {
|
||||||
"Time-critical class",
|
"Time-critical class",
|
||||||
|
"Server priority class",
|
||||||
|
"Regular priority class",
|
||||||
|
"Idle priority class",
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { IDLE_PRIO_PROC = 0,
|
enum { TIME_CRIT_PROC = 0,
|
||||||
REGL_PRIO_PROC = 1,
|
SERV_PRIO_PROC = 1,
|
||||||
SERV_PRIO_PROC = 2,
|
REGL_PRIO_PROC = 2,
|
||||||
TIME_CRIT_PROC = 3,
|
IDLE_PRIO_PROC = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -110,8 +112,8 @@ Process_t *CompareProcs(Process_t *proc1, Process_t *proc2)
|
||||||
{
|
{
|
||||||
KalAssert(proc1 && proc2);
|
KalAssert(proc1 && proc2);
|
||||||
|
|
||||||
if (proc1->prioClass > proc2->prioClass) return proc1;
|
if (proc1->prioClass < proc2->prioClass) return proc1;
|
||||||
if (proc1->prioClass < proc2->prioClass) return proc2;
|
if (proc1->prioClass > proc2->prioClass) return proc2;
|
||||||
|
|
||||||
if (proc1->prioLevel > proc2->prioLevel) return proc1;
|
if (proc1->prioLevel > proc2->prioLevel) return proc1;
|
||||||
if (proc1->prioLevel < proc2->prioLevel) return proc2;
|
if (proc1->prioLevel < proc2->prioLevel) return proc2;
|
||||||
|
@ -125,7 +127,7 @@ Process_t *CompareProcs(Process_t *proc1, Process_t *proc2)
|
||||||
static inline
|
static inline
|
||||||
void SchedThisProcUnlocked(Process_t *proc)
|
void SchedThisProcUnlocked(Process_t *proc)
|
||||||
{
|
{
|
||||||
KalAssert(proc && proc->procState == STATE_RUNNABLE);
|
KalAssert(proc && proc->procState == STATE_RUNNABLE && !proc->schedNode);
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
ListNode_t *iterNode = NULL;
|
ListNode_t *iterNode = NULL;
|
||||||
|
@ -136,13 +138,15 @@ void SchedThisProcUnlocked(Process_t *proc)
|
||||||
|
|
||||||
proc->schedNode = procNode;
|
proc->schedNode = procNode;
|
||||||
|
|
||||||
//printdbg("Adding process %d to '%s'\n", proc->pid, PrioClassesNames[proc->prioClass]);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find a process with lesser priority
|
// Find a process with lesser priority
|
||||||
//
|
//
|
||||||
for (iterNode = head->first; iterNode; iterNode = iterNode->next) {
|
for (iterNode = head->first; iterNode; iterNode = iterNode->next) {
|
||||||
if (proc->prioLevel > GetNodeData(iterNode, Process_t *)->prioLevel) {
|
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);
|
AddNodeBefore(head, iterNode, procNode);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -197,34 +201,20 @@ void BlockCurProc(void)
|
||||||
|
|
||||||
ListNode_t *procNode = GetCurProc()->schedNode;
|
ListNode_t *procNode = GetCurProc()->schedNode;
|
||||||
|
|
||||||
|
KalAssert(procNode && "Blocking non-scheduled process");
|
||||||
|
|
||||||
GetCurProc()->procState = STATE_BLOCKED;
|
GetCurProc()->procState = STATE_BLOCKED;
|
||||||
RemoveNode(procNode->head, procNode);
|
RemoveNode(procNode->head, procNode);
|
||||||
|
|
||||||
|
GetCurProc()->schedNode = NULL;
|
||||||
SetCurProc(SelectSchedNext());
|
SetCurProc(SelectSchedNext());
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
static inline
|
||||||
// Should we schedule another process?
|
void ReSchedCurProc(void)
|
||||||
// Called at each tick
|
|
||||||
//
|
|
||||||
void SchedOnTick(void)
|
|
||||||
{
|
{
|
||||||
Process_t *procNext;
|
KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING);
|
||||||
Process_t *winner;
|
KalAssert(GetCurProc()->schedNode);
|
||||||
|
|
||||||
SchedLock();
|
|
||||||
|
|
||||||
//
|
|
||||||
// We're either idle or running something
|
|
||||||
//
|
|
||||||
KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Has current process spent his timeslice?
|
|
||||||
// (To be handled in CPU decisions function)
|
|
||||||
//
|
|
||||||
if (GetCurProc() != NULL) {
|
|
||||||
if (GetCurProc()->timeSlice <= 1) {
|
|
||||||
|
|
||||||
// Restore default attributes, cancelling boosts
|
// Restore default attributes, cancelling boosts
|
||||||
GetCurProc()->prioClass = GetCurProc()->defPrioClass;
|
GetCurProc()->prioClass = GetCurProc()->defPrioClass;
|
||||||
|
@ -234,16 +224,42 @@ void SchedOnTick(void)
|
||||||
|
|
||||||
// Remove from list
|
// Remove from list
|
||||||
RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode);
|
RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode);
|
||||||
|
GetCurProc()->schedNode = NULL;
|
||||||
|
|
||||||
// Schedule again, with default attributes now
|
// Schedule again, with default attributes now
|
||||||
SchedThisProcUnlocked(GetCurProc());
|
SchedThisProcUnlocked(GetCurProc());
|
||||||
|
}
|
||||||
|
|
||||||
// Mark as idle
|
//
|
||||||
SetCurProc(NULL);
|
// Should we schedule another process?
|
||||||
|
// Called at each tick
|
||||||
|
//
|
||||||
|
void SchedOnTick(void)
|
||||||
|
{
|
||||||
|
SchedLock();
|
||||||
|
|
||||||
|
Process_t *procNext, *winner, *previous = GetCurProc();
|
||||||
|
|
||||||
|
//
|
||||||
|
// We're either idle or running something
|
||||||
|
//
|
||||||
|
KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Have the current process spent its timeslice?
|
||||||
|
// (To be handled in CPU decisions function)
|
||||||
|
//
|
||||||
|
if (GetCurProc() != NULL) {
|
||||||
|
if (GetCurProc()->timeSlice <= 1) {
|
||||||
|
// Re-schedule
|
||||||
|
ReSchedCurProc();
|
||||||
|
|
||||||
|
// See next 'if' statement
|
||||||
|
_SetCurProc(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Otherwise, make him lose a tick
|
// Otherwise, make it lose a tick
|
||||||
//
|
//
|
||||||
else {
|
else {
|
||||||
GetCurProc()->timeSlice--;
|
GetCurProc()->timeSlice--;
|
||||||
|
@ -268,8 +284,10 @@ void SchedOnTick(void)
|
||||||
// Yes, procNext should preempt current process
|
// Yes, procNext should preempt current process
|
||||||
//
|
//
|
||||||
if (winner == procNext) {
|
if (winner == procNext) {
|
||||||
GetCurProc()->procState = STATE_RUNNABLE;
|
// Re-schedule
|
||||||
SchedThisProcUnlocked(GetCurProc());
|
ReSchedCurProc();
|
||||||
|
|
||||||
|
// Switch to procNext
|
||||||
SetCurProc(procNext);
|
SetCurProc(procNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,32 +296,10 @@ void SchedOnTick(void)
|
||||||
//
|
//
|
||||||
leave:
|
leave:
|
||||||
SchedUnlock();
|
SchedUnlock();
|
||||||
}
|
|
||||||
|
|
||||||
#define PrintProc(proc) printdbg("{ %d, '%s', %d , %d}\n", (proc)->pid, \
|
if (GetCurProc() != NULL && GetCurProc() != previous) {
|
||||||
PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice);
|
// XXX context switch
|
||||||
|
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
puts("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -312,7 +308,6 @@ void PrintList(ListHead_t *head)
|
||||||
void InitSched(void)
|
void InitSched(void)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
Process_t *proc;
|
|
||||||
|
|
||||||
SchedLock();
|
SchedLock();
|
||||||
|
|
||||||
|
@ -355,6 +350,33 @@ void FiniSched(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _KALEID_KERNEL
|
#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)
|
int main(void)
|
||||||
{
|
{
|
||||||
InitSched();
|
InitSched();
|
||||||
|
@ -379,7 +401,17 @@ int main(void)
|
||||||
|
|
||||||
int tick = 0;
|
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);
|
printf("Tick %d - Running: ", tick);
|
||||||
|
|
||||||
if (GetCurProc() == NULL) {
|
if (GetCurProc() == NULL) {
|
||||||
|
@ -390,14 +422,11 @@ int main(void)
|
||||||
PrintProc(GetCurProc());
|
PrintProc(GetCurProc());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tick == 9 || tick == 14) {
|
|
||||||
puts("Blocking current process");
|
|
||||||
BlockCurProc();
|
|
||||||
}
|
|
||||||
|
|
||||||
SchedOnTick();
|
SchedOnTick();
|
||||||
|
|
||||||
//puts("\n---------------");
|
if (tick == 50) // already done
|
||||||
|
puts("Re-scheduling process 0");
|
||||||
|
|
||||||
tick++;
|
tick++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,5 +434,6 @@ int main(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue