CRT library stuff
This commit is contained in:
parent
2bf7929ce2
commit
98c2dd8502
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -10,59 +10,89 @@
|
|||
#include <kaleid.h>
|
||||
|
||||
//
|
||||
// Digits table for bases <=36
|
||||
// Digits table for bases <=36 (unused)
|
||||
//
|
||||
static const char digits[] =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
//
|
||||
// Integer to string in any base between 2 and 36 (included)
|
||||
//
|
||||
|
||||
#if defined(_NEED_ITOA)
|
||||
|
||||
char *itoa(int i, char *str, int base)
|
||||
#define _IL_MIN INT_MIN
|
||||
#define _IL_MIN_STRING "-2147483648"
|
||||
|
||||
#elif defined(_NEED_LTOA)
|
||||
|
||||
char *ltoa(long i, char *str, int base)
|
||||
#define _IL_MIN LONG_MIN
|
||||
#define _IL_MIN_STRING "-9223372036854775808"
|
||||
|
||||
#elif defined(_NEED_UTOA)
|
||||
|
||||
char *utoa(uint i, char *str, int base)
|
||||
|
||||
#elif defined(_NEED_ULTOA)
|
||||
|
||||
char *ultoa(ulong i, char *str, int base)
|
||||
|
||||
#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) {
|
||||
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 +105,13 @@ char *ultoa(ulong i, char *str, int base)
|
|||
//
|
||||
// Reverse the string
|
||||
//
|
||||
return strrev2(orig);
|
||||
orig = strrev2(orig);
|
||||
|
||||
//
|
||||
// End of conversion
|
||||
//
|
||||
leave:
|
||||
return orig;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -23,11 +23,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef INITOK
|
||||
#define INITOK ((unsigned int)0xCAFEBABE)
|
||||
#define NULL 0L
|
||||
#endif
|
||||
|
||||
//------------------------------------------//
|
||||
|
@ -61,8 +57,8 @@
|
|||
// Attributes and macros //
|
||||
//------------------------------------------//
|
||||
|
||||
#ifndef PACKED
|
||||
#define PACKED __attribute__((__packed__))
|
||||
#ifndef _PACKED
|
||||
#define _PACKED __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#ifndef noreturn
|
||||
|
@ -77,6 +73,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 //
|
||||
//------------------------------------------//
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define _KALERROR_H
|
||||
|
||||
//------------------------------------------//
|
||||
// Preprocessor constants //
|
||||
// "errno" values //
|
||||
//------------------------------------------//
|
||||
|
||||
// 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
|
||||
*RemoveNode(ListHead_t *head, ListNode_t *node)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -59,6 +59,11 @@ typedef enum {
|
|||
// Multiprocessor misc. //
|
||||
//------------------------------------------//
|
||||
|
||||
|
||||
#ifndef INITOK
|
||||
#define INITOK ((unsigned int)0xCAFEBABE)
|
||||
#endif
|
||||
|
||||
#ifndef NCPU
|
||||
#define NCPU 4
|
||||
#endif
|
||||
|
@ -108,12 +113,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 +183,6 @@ void WriteByteOnPort(port_t port, port_t val)
|
|||
static inline
|
||||
uchar ReadByteFromPort(port_t port)
|
||||
{
|
||||
|
||||
KalAssert(FALSE && ENOSYS);
|
||||
(void)port;
|
||||
return 0;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 //
|
||||
//------------------------------------------//
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -66,12 +66,13 @@ 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[] = {
|
||||
const char *PrioClassesNames[] = {
|
||||
"Idle priority class",
|
||||
"Regular priority class",
|
||||
"Server priority class",
|
||||
|
@ -203,28 +204,10 @@ void BlockCurProc(void)
|
|||
SetCurProc(SelectSchedNext());
|
||||
}
|
||||
|
||||
//
|
||||
// Should we schedule another process?
|
||||
// Called at each tick
|
||||
//
|
||||
void SchedOnTick(void)
|
||||
static inline
|
||||
void ReSchedCurProc(void)
|
||||
{
|
||||
Process_t *procNext;
|
||||
Process_t *winner;
|
||||
|
||||
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) {
|
||||
KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING);
|
||||
|
||||
// Restore default attributes, cancelling boosts
|
||||
GetCurProc()->prioClass = GetCurProc()->defPrioClass;
|
||||
|
@ -234,16 +217,42 @@ void SchedOnTick(void)
|
|||
|
||||
// Remove from list
|
||||
RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode);
|
||||
GetCurProc()->schedNode = NULL;
|
||||
|
||||
// Schedule again, with default attributes now
|
||||
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 {
|
||||
GetCurProc()->timeSlice--;
|
||||
|
@ -268,8 +277,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 +289,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("");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -355,6 +344,33 @@ void FiniSched(void)
|
|||
}
|
||||
|
||||
#ifndef _KALEID_KERNEL
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
puts("");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
InitSched();
|
||||
|
@ -379,7 +395,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[2].procState = STATE_RUNNABLE;
|
||||
SchedThisProc(&procs[2]);
|
||||
}
|
||||
|
||||
printf("Tick %d - Running: ", tick);
|
||||
|
||||
if (GetCurProc() == NULL) {
|
||||
|
@ -390,14 +416,8 @@ int main(void)
|
|||
PrintProc(GetCurProc());
|
||||
}
|
||||
|
||||
if (tick == 9 || tick == 14) {
|
||||
puts("Blocking current process");
|
||||
BlockCurProc();
|
||||
}
|
||||
|
||||
SchedOnTick();
|
||||
|
||||
//puts("\n---------------");
|
||||
tick++;
|
||||
}
|
||||
|
||||
|
@ -405,5 +425,6 @@ int main(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue