user_space #4
@ -4,7 +4,7 @@
|
|||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
|
||||||
exception_handler exception_handler_array[EXCEPTION_NUM] = {
|
exception_handler exception_handler_array[EXCEPTION_NUM] = {
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cpu_context.h"
|
|
||||||
#include "mem.h"
|
|
||||||
|
|
||||||
#define KTHREAD_NAME_MAX_LENGTH 32
|
|
||||||
#define KTHREAD_DEFAULT_STACK_SIZE PAGE_SIZE
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
RUNNING,
|
|
||||||
READY,
|
|
||||||
SLEEPING,
|
|
||||||
WAITING,
|
|
||||||
EXITING
|
|
||||||
} kthread_state;
|
|
||||||
|
|
||||||
struct thread {
|
|
||||||
char name[KTHREAD_NAME_MAX_LENGTH];
|
|
||||||
struct cpu_state *cpuState;
|
|
||||||
kthread_state state;
|
|
||||||
vaddr_t stackAddr;
|
|
||||||
size_t stackSize;
|
|
||||||
unsigned long jiffiesSleeping;
|
|
||||||
int sleepHaveTimeouted;
|
|
||||||
struct thread *next;
|
|
||||||
struct thread *prev;
|
|
||||||
struct thread*timeNext;
|
|
||||||
struct thread *timePrev;
|
|
||||||
};
|
|
||||||
|
|
||||||
int kthreadSetup(vaddr_t mainStack, size_t mainStackSize);
|
|
||||||
void kthreadExit();
|
|
||||||
|
|
||||||
struct thread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func, void *args);
|
|
||||||
void kthreadDelete(struct thread *thread);
|
|
||||||
|
|
||||||
struct thread *kthreadSelectNext();
|
|
||||||
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu);
|
|
||||||
|
|
||||||
int kthreadYield();
|
|
||||||
int kthreadWait(struct thread *current, struct thread *next, unsigned long msec);
|
|
||||||
int kthreadUnsched(struct thread *th);
|
|
||||||
int kthreadMsleep(unsigned long msec);
|
|
||||||
int kthreadOnJieffiesTick();
|
|
||||||
struct thread *getCurrentThread();
|
|
||||||
int kthreadAddThread(struct thread *th);
|
|
10
core/main.c
10
core/main.c
@ -9,7 +9,7 @@
|
|||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "mmuContext.h"
|
#include "mmuContext.h"
|
||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
@ -32,7 +32,7 @@ void idleThread(void *arg)
|
|||||||
(void)arg;
|
(void)arg;
|
||||||
while (1) {
|
while (1) {
|
||||||
VGAPrintf(GREEN, BLACK, 0, VGA_HEIGHT - 1, "%d", (jiffies / HZ));
|
VGAPrintf(GREEN, BLACK, 0, VGA_HEIGHT - 1, "%d", (jiffies / HZ));
|
||||||
kthreadYield();
|
threadYield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,8 +168,8 @@ void kmain(unsigned long magic, unsigned long addr)
|
|||||||
cpu_context_subsystem_setup();
|
cpu_context_subsystem_setup();
|
||||||
|
|
||||||
printf("[Setup] thread system\n");
|
printf("[Setup] thread system\n");
|
||||||
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
|
threadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
|
||||||
kthreadCreate("idle ", idleThread, NULL);
|
threadCreate("idle ", idleThread, NULL);
|
||||||
|
|
||||||
irqSetRoutine(IRQ_TIMER, pit_handler);
|
irqSetRoutine(IRQ_TIMER, pit_handler);
|
||||||
|
|
||||||
@ -187,5 +187,5 @@ void kmain(unsigned long magic, unsigned long addr)
|
|||||||
|
|
||||||
// There is no real caller behind this point
|
// There is no real caller behind this point
|
||||||
// So finish this by ourself
|
// So finish this by ourself
|
||||||
kthreadExit();
|
threadExit();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
@ -10,14 +10,14 @@
|
|||||||
static struct thread *currentThread;
|
static struct thread *currentThread;
|
||||||
static struct thread *threadWithTimeout;
|
static struct thread *threadWithTimeout;
|
||||||
|
|
||||||
void kthreadExit()
|
void threadExit()
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
|
|
||||||
struct thread *current = currentThread;
|
struct thread *current = currentThread;
|
||||||
struct thread *next = kthreadSelectNext();
|
struct thread *next = threadSelectNext();
|
||||||
|
|
||||||
if (next == current)
|
if (next == current)
|
||||||
assert("cannot exit thread");
|
assert("cannot exit thread");
|
||||||
@ -25,7 +25,7 @@ void kthreadExit()
|
|||||||
currentThread->state = EXITING;
|
currentThread->state = EXITING;
|
||||||
currentThread = next;
|
currentThread = next;
|
||||||
currentThread->state = RUNNING;
|
currentThread->state = RUNNING;
|
||||||
cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete,
|
cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)threadDelete,
|
||||||
(uint32_t)current);
|
(uint32_t)current);
|
||||||
|
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
@ -33,10 +33,10 @@ void kthreadExit()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kthreadSetup(vaddr_t mainStack, size_t mainStackSize)
|
int threadSetup(vaddr_t mainStack, size_t mainStackSize)
|
||||||
{
|
{
|
||||||
struct thread *current = (struct thread *)malloc(sizeof(struct thread));
|
struct thread *current = (struct thread *)malloc(sizeof(struct thread));
|
||||||
strzcpy(current->name, "[KINIT]", KTHREAD_NAME_MAX_LENGTH);
|
strzcpy(current->name, "[KINIT]", THREAD_NAME_MAX_LENGTH);
|
||||||
current->stackAddr = mainStack;
|
current->stackAddr = mainStack;
|
||||||
current->stackSize = mainStackSize;
|
current->stackSize = mainStackSize;
|
||||||
|
|
||||||
@ -48,31 +48,31 @@ int kthreadSetup(vaddr_t mainStack, size_t mainStackSize)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func, void *args)
|
struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, void *args)
|
||||||
{
|
{
|
||||||
struct thread *thread = (struct thread *)malloc(sizeof(struct thread));
|
struct thread *thread = (struct thread *)malloc(sizeof(struct thread));
|
||||||
if (!thread)
|
if (!thread)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
thread->stackAddr = (vaddr_t)malloc(KTHREAD_DEFAULT_STACK_SIZE);
|
thread->stackAddr = (vaddr_t)malloc(THREAD_DEFAULT_STACK_SIZE);
|
||||||
if(!thread->stackAddr)
|
if(!thread->stackAddr)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Alloc stack at 0x%x struct at 0x%x\n", thread->stackAddr, thread);
|
printf("Alloc stack at 0x%x struct at 0x%x\n", thread->stackAddr, thread);
|
||||||
#endif
|
#endif
|
||||||
thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE;
|
thread->stackSize = THREAD_DEFAULT_STACK_SIZE;
|
||||||
|
|
||||||
if (!thread->stackAddr)
|
if (!thread->stackAddr)
|
||||||
goto free_mem;
|
goto free_mem;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
strzcpy(thread->name, name, KTHREAD_NAME_MAX_LENGTH);
|
strzcpy(thread->name, name, THREAD_NAME_MAX_LENGTH);
|
||||||
else
|
else
|
||||||
strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH);
|
strzcpy(thread->name, "[UNKNOW]", THREAD_NAME_MAX_LENGTH);
|
||||||
|
|
||||||
if (cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args,
|
if (cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args,
|
||||||
thread->stackAddr, thread->stackSize,
|
thread->stackAddr, thread->stackSize,
|
||||||
(cpu_kstate_function_arg1_t *)kthreadExit, 0))
|
(cpu_kstate_function_arg1_t *)threadExit, 0))
|
||||||
goto free_mem;
|
goto free_mem;
|
||||||
|
|
||||||
thread->state = READY;
|
thread->state = READY;
|
||||||
@ -87,7 +87,7 @@ free_mem:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kthreadDelete(struct thread *thread)
|
void threadDelete(struct thread *thread)
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
@ -101,7 +101,7 @@ void kthreadDelete(struct thread *thread)
|
|||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread *kthreadSelectNext()
|
struct thread *threadSelectNext()
|
||||||
{
|
{
|
||||||
struct thread *nextThread;
|
struct thread *nextThread;
|
||||||
int idx;
|
int idx;
|
||||||
@ -114,14 +114,14 @@ struct thread *kthreadSelectNext()
|
|||||||
return currentThread;
|
return currentThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu)
|
struct cpu_state *threadSwitch(struct cpu_state *prevCpu)
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct thread *nextThread;
|
struct thread *nextThread;
|
||||||
|
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
|
|
||||||
nextThread = kthreadSelectNext();
|
nextThread = threadSelectNext();
|
||||||
currentThread->cpuState = prevCpu;
|
currentThread->cpuState = prevCpu;
|
||||||
currentThread->state = READY;
|
currentThread->state = READY;
|
||||||
currentThread = nextThread;
|
currentThread = nextThread;
|
||||||
@ -132,7 +132,7 @@ struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu)
|
|||||||
return nextThread->cpuState;
|
return nextThread->cpuState;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kthreadOnJieffiesTick()
|
int threadOnJieffiesTick()
|
||||||
{
|
{
|
||||||
struct thread *nextThread;
|
struct thread *nextThread;
|
||||||
int idx;
|
int idx;
|
||||||
@ -154,7 +154,7 @@ int kthreadOnJieffiesTick()
|
|||||||
if (!nextThread->jiffiesSleeping) {
|
if (!nextThread->jiffiesSleeping) {
|
||||||
nextThread->sleepHaveTimeouted = 1;
|
nextThread->sleepHaveTimeouted = 1;
|
||||||
list_delete_named(threadWithTimeout, nextThread, timePrev, timeNext);
|
list_delete_named(threadWithTimeout, nextThread, timePrev, timeNext);
|
||||||
kthreadAddThread(nextThread);
|
threadAddThread(nextThread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ int kthreadOnJieffiesTick()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kthreadUnsched(struct thread *th)
|
int threadUnsched(struct thread *th)
|
||||||
{
|
{
|
||||||
list_delete(currentThread, th);
|
list_delete(currentThread, th);
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ int kthreadUnsched(struct thread *th)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Must be called with IRQ disabled
|
// Must be called with IRQ disabled
|
||||||
int kthreadWait(struct thread *current, struct thread *next, unsigned long msec)
|
int threadWait(struct thread *current, struct thread *next, unsigned long msec)
|
||||||
{
|
{
|
||||||
if (current == next) {
|
if (current == next) {
|
||||||
assertmsg(0, "Cannot yield from %s to %s\n", current->name, next->name);
|
assertmsg(0, "Cannot yield from %s to %s\n", current->name, next->name);
|
||||||
@ -192,12 +192,12 @@ int kthreadWait(struct thread *current, struct thread *next, unsigned long msec)
|
|||||||
return current->sleepHaveTimeouted;
|
return current->sleepHaveTimeouted;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kthreadYield()
|
int threadYield()
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
struct thread *next = kthreadSelectNext();
|
struct thread *next = threadSelectNext();
|
||||||
struct thread *current = currentThread;
|
struct thread *current = currentThread;
|
||||||
|
|
||||||
if (current == next) {
|
if (current == next) {
|
||||||
@ -219,7 +219,7 @@ int kthreadYield()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kthreadMsleep(unsigned long msec)
|
int threadMsleep(unsigned long msec)
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct thread *next, *current;
|
struct thread *next, *current;
|
||||||
@ -233,7 +233,7 @@ int kthreadMsleep(unsigned long msec)
|
|||||||
current->state = SLEEPING;
|
current->state = SLEEPING;
|
||||||
current->sleepHaveTimeouted = 0;
|
current->sleepHaveTimeouted = 0;
|
||||||
current->jiffiesSleeping = msecs_to_jiffies(msec);
|
current->jiffiesSleeping = msecs_to_jiffies(msec);
|
||||||
next = kthreadSelectNext();
|
next = threadSelectNext();
|
||||||
|
|
||||||
assert(next != current);
|
assert(next != current);
|
||||||
assert(next->state == READY);
|
assert(next->state == READY);
|
||||||
@ -250,7 +250,7 @@ struct thread *getCurrentThread()
|
|||||||
return currentThread;
|
return currentThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kthreadAddThread(struct thread *th)
|
int threadAddThread(struct thread *th)
|
||||||
{
|
{
|
||||||
if (th->state == READY)
|
if (th->state == READY)
|
||||||
return 0;
|
return 0;
|
47
core/thread.h
Normal file
47
core/thread.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cpu_context.h"
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
#define THREAD_NAME_MAX_LENGTH 32
|
||||||
|
#define THREAD_DEFAULT_STACK_SIZE PAGE_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RUNNING,
|
||||||
|
READY,
|
||||||
|
SLEEPING,
|
||||||
|
WAITING,
|
||||||
|
EXITING
|
||||||
|
} thread_state;
|
||||||
|
|
||||||
|
struct thread {
|
||||||
|
char name[THREAD_NAME_MAX_LENGTH];
|
||||||
|
struct cpu_state *cpuState;
|
||||||
|
thread_state state;
|
||||||
|
vaddr_t stackAddr;
|
||||||
|
size_t stackSize;
|
||||||
|
unsigned long jiffiesSleeping;
|
||||||
|
int sleepHaveTimeouted;
|
||||||
|
struct thread *next;
|
||||||
|
struct thread *prev;
|
||||||
|
struct thread*timeNext;
|
||||||
|
struct thread *timePrev;
|
||||||
|
};
|
||||||
|
|
||||||
|
int threadSetup(vaddr_t mainStack, size_t mainStackSize);
|
||||||
|
void threadExit();
|
||||||
|
|
||||||
|
struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, void *args);
|
||||||
|
void threadDelete(struct thread *thread);
|
||||||
|
|
||||||
|
struct thread *threadSelectNext();
|
||||||
|
struct cpu_state *threadSwitch(struct cpu_state *prevCpu);
|
||||||
|
|
||||||
|
int threadYield();
|
||||||
|
int threadWait(struct thread *current, struct thread *next, unsigned long msec);
|
||||||
|
int threadUnsched(struct thread *th);
|
||||||
|
int threadMsleep(unsigned long msec);
|
||||||
|
int threadOnJieffiesTick();
|
||||||
|
struct thread *getCurrentThread();
|
||||||
|
int threadAddThread(struct thread *th);
|
10
core/wait.c
10
core/wait.c
@ -1,5 +1,5 @@
|
|||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ int wakeUp(struct wait_queue *wq)
|
|||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
list_collapse(wq->thread, th)
|
list_collapse(wq->thread, th)
|
||||||
{
|
{
|
||||||
kthreadAddThread(th);
|
threadAddThread(th);
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
@ -54,11 +54,11 @@ int waitTimeout(struct wait_queue *wq, unsigned long msec)
|
|||||||
|
|
||||||
current = getCurrentThread();
|
current = getCurrentThread();
|
||||||
current->state = WAITING;
|
current->state = WAITING;
|
||||||
next = kthreadSelectNext();
|
next = threadSelectNext();
|
||||||
kthreadUnsched(current);
|
threadUnsched(current);
|
||||||
|
|
||||||
list_add_tail(wq->thread, current);
|
list_add_tail(wq->thread, current);
|
||||||
ret = kthreadWait(current, next, msec);
|
ret = threadWait(current, next, msec);
|
||||||
|
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
struct wait_queue {
|
struct wait_queue {
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
|
@ -39,32 +39,32 @@ class CustomPrettyPrinterLocator(PrettyPrinter):
|
|||||||
if typename is None:
|
if typename is None:
|
||||||
typename = val.type.name
|
typename = val.type.name
|
||||||
|
|
||||||
if typename == "kthread":
|
if typename == "thread":
|
||||||
return KthreadPrettyPrinter(val)
|
return KthreadPrettyPrinter(val)
|
||||||
|
|
||||||
|
|
||||||
class KthreadListDumpCmd(gdb.Command):
|
class threadListDumpCmd(gdb.Command):
|
||||||
"""Prints the kthread list"""
|
"""Prints the thread list"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(KthreadListDumpCmd, self).__init__(
|
super(threadListDumpCmd, self).__init__(
|
||||||
"kthread_list_dump", gdb.COMMAND_USER
|
"thread_list_dump", gdb.COMMAND_USER
|
||||||
)
|
)
|
||||||
|
|
||||||
def _kthread_list_to_str(self, val):
|
def _thread_list_to_str(self, val):
|
||||||
"""Walk through the Kthread list.
|
"""Walk through the Kthread list.
|
||||||
|
|
||||||
We will simply follow the 'next' pointers until we encounter the HEAD again
|
We will simply follow the 'next' pointers until we encounter the HEAD again
|
||||||
"""
|
"""
|
||||||
idx = 0
|
idx = 0
|
||||||
head = val
|
head = val
|
||||||
kthread_ptr = val
|
thread_ptr = val
|
||||||
result = ""
|
result = ""
|
||||||
while kthread_ptr != 0 and (idx == 0 or kthread_ptr != head):
|
while thread_ptr != 0 and (idx == 0 or thread_ptr != head):
|
||||||
result += "\n%d: %s" % (idx, KthreadPrettyPrinter(kthread_ptr).to_string())
|
result += "\n%d: %s" % (idx, KthreadPrettyPrinter(thread_ptr).to_string())
|
||||||
kthread_ptr = kthread_ptr["next"]
|
thread_ptr = thread_ptr["next"]
|
||||||
idx += 1
|
idx += 1
|
||||||
result = ("Found a Linked List with %d kthread:" % idx) + result
|
result = ("Found a Linked List with %d thread:" % idx) + result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def complete(self, text, word):
|
def complete(self, text, word):
|
||||||
@ -77,14 +77,14 @@ class KthreadListDumpCmd(gdb.Command):
|
|||||||
# to do argument parsing
|
# to do argument parsing
|
||||||
print("Args Passed: %s" % args)
|
print("Args Passed: %s" % args)
|
||||||
if args:
|
if args:
|
||||||
kthread_ptr_val = gdb.parse_and_eval(args)
|
thread_ptr_val = gdb.parse_and_eval(args)
|
||||||
else:
|
else:
|
||||||
kthread_ptr_val = gdb.parse_and_eval("currentThread")
|
thread_ptr_val = gdb.parse_and_eval("currentThread")
|
||||||
if str(kthread_ptr_val.type) != "struct kthread *":
|
if str(thread_ptr_val.type) != "struct thread *":
|
||||||
print("Expected pointer argument of type (struct kthread *)")
|
print("Expected pointer argument of type (struct thread *)")
|
||||||
return
|
return
|
||||||
|
|
||||||
print(self._kthread_list_to_str(kthread_ptr_val))
|
print(self._thread_list_to_str(thread_ptr_val))
|
||||||
|
|
||||||
|
|
||||||
class PhyMemDescListDumpCmd(gdb.Command):
|
class PhyMemDescListDumpCmd(gdb.Command):
|
||||||
@ -175,6 +175,7 @@ class PrintStructC99Cmd(gdb.Command):
|
|||||||
rr_rval = rr_s[1].strip()
|
rr_rval = rr_s[1].strip()
|
||||||
print(' ' * hs + '.' + rr_s[0] + '= ' + rr_rval)
|
print(' ' * hs + '.' + rr_s[0] + '= ' + rr_rval)
|
||||||
|
|
||||||
|
|
||||||
class ListDumpCmd(gdb.Command):
|
class ListDumpCmd(gdb.Command):
|
||||||
"""Prints a linked list"""
|
"""Prints a linked list"""
|
||||||
|
|
||||||
@ -190,13 +191,13 @@ class ListDumpCmd(gdb.Command):
|
|||||||
"""
|
"""
|
||||||
idx = 0
|
idx = 0
|
||||||
head = val
|
head = val
|
||||||
kthread_ptr = val
|
thread_ptr = val
|
||||||
result = ""
|
result = ""
|
||||||
while kthread_ptr != 0 and (idx == 0 or kthread_ptr != head):
|
while thread_ptr != 0 and (idx == 0 or thread_ptr != head):
|
||||||
result += gdb.execute('p *({}){}'.format(str(kthread_ptr.type),kthread_ptr), to_string=True)
|
result += gdb.execute('p *({}){}'.format(str(thread_ptr.type),thread_ptr), to_string=True)
|
||||||
kthread_ptr = kthread_ptr["next"]
|
thread_ptr = thread_ptr["next"]
|
||||||
idx += 1
|
idx += 1
|
||||||
result = ("Found a Linked List with %d items:" % idx) + "\n"+ result
|
result = ("Found a Linked List with %d items:" % idx) + "\n" + result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def complete(self, text, word):
|
def complete(self, text, word):
|
||||||
@ -220,8 +221,9 @@ class ListDumpCmd(gdb.Command):
|
|||||||
|
|
||||||
print(self._print_list(ptr_val))
|
print(self._print_list(ptr_val))
|
||||||
|
|
||||||
|
|
||||||
register_pretty_printer(None, CustomPrettyPrinterLocator(), replace=True)
|
register_pretty_printer(None, CustomPrettyPrinterLocator(), replace=True)
|
||||||
KthreadListDumpCmd()
|
threadListDumpCmd()
|
||||||
PhyMemDescListDumpCmd()
|
PhyMemDescListDumpCmd()
|
||||||
PrintStructC99Cmd()
|
PrintStructC99Cmd()
|
||||||
ListDumpCmd()
|
ListDumpCmd()
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
// from
|
// from
|
||||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
int pitSetup(unsigned int freq)
|
int pitSetup(unsigned int freq)
|
||||||
@ -20,8 +20,8 @@ int pitSetup(unsigned int freq)
|
|||||||
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu)
|
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu)
|
||||||
{
|
{
|
||||||
__atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED);
|
__atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED);
|
||||||
kthreadOnJieffiesTick();
|
threadOnJieffiesTick();
|
||||||
// Uncomment for non-preemptible kernel
|
// Uncomment for non-preemptible kernel
|
||||||
// return prevCpu;
|
// return prevCpu;
|
||||||
return kthreadSwitch(prevCpu);
|
return threadSwitch(prevCpu);
|
||||||
}
|
}
|
||||||
|
34
tests/test.c
34
tests/test.c
@ -4,7 +4,7 @@
|
|||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "cpu_context.h"
|
#include "cpu_context.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "kthread.h"
|
#include "thread.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "mmuContext.h"
|
#include "mmuContext.h"
|
||||||
@ -274,7 +274,7 @@ static void kthread1(void *strIn)
|
|||||||
char *str = (char *)strIn;
|
char *str = (char *)strIn;
|
||||||
for (; *str != '\n'; str++) {
|
for (; *str != '\n'; str++) {
|
||||||
printf("kth1: %c\n", *str);
|
printf("kth1: %c\n", *str);
|
||||||
kthreadYield();
|
threadYield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ static void kthread2(void *strIn)
|
|||||||
char *str = (char *)strIn;
|
char *str = (char *)strIn;
|
||||||
for (; *str != '\n'; str++) {
|
for (; *str != '\n'; str++) {
|
||||||
printf("kth2: %c\n", *str);
|
printf("kth2: %c\n", *str);
|
||||||
kthreadYield();
|
threadYield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,11 +296,11 @@ void sleepThread(void *arg)
|
|||||||
while (secSleep < 5) {
|
while (secSleep < 5) {
|
||||||
// printf("Sleeping loop %d\n", secSleep);
|
// printf("Sleeping loop %d\n", secSleep);
|
||||||
secSleep++;
|
secSleep++;
|
||||||
kthreadMsleep(1000);
|
threadMsleep(1000);
|
||||||
}
|
}
|
||||||
unsigned long ellapsedTime = jiffies_to_msecs(jiffies - initialJiffies);
|
unsigned long ellapsedTime = jiffies_to_msecs(jiffies - initialJiffies);
|
||||||
assertmsg(ellapsedTime >= 5000 && ellapsedTime < 5100, "ellapsedTime %d\n", ellapsedTime);
|
assertmsg(ellapsedTime >= 5000 && ellapsedTime < 5100, "ellapsedTime %d\n", ellapsedTime);
|
||||||
kthreadMsleep(0);
|
threadMsleep(0);
|
||||||
printf("I should never be showed\n");
|
printf("I should never be showed\n");
|
||||||
assert(1);
|
assert(1);
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ void mutThread(void *arg)
|
|||||||
while (test > 0) {
|
while (test > 0) {
|
||||||
mutexLock(&mutexTest);
|
mutexLock(&mutexTest);
|
||||||
printf("%s sleep\n", (char *)arg);
|
printf("%s sleep\n", (char *)arg);
|
||||||
kthreadMsleep(1000);
|
threadMsleep(1000);
|
||||||
printf("%s up\n", (char *)arg);
|
printf("%s up\n", (char *)arg);
|
||||||
mutexUnlock(&mutexTest);
|
mutexUnlock(&mutexTest);
|
||||||
test--;
|
test--;
|
||||||
@ -336,17 +336,17 @@ void testKthread()
|
|||||||
{
|
{
|
||||||
mutexInit(&mutexTest);
|
mutexInit(&mutexTest);
|
||||||
// It is not expected to have necessarily "Hello world\n" properly written
|
// It is not expected to have necessarily "Hello world\n" properly written
|
||||||
kthreadCreate("Test2", (cpu_kstate_function_arg1_t *)kthread2, (void *)"el ol\n");
|
threadCreate("Test2", (cpu_kstate_function_arg1_t *)kthread2, (void *)"el ol\n");
|
||||||
kthreadCreate("Test1", (cpu_kstate_function_arg1_t *)kthread1, (void *)"Hlowrd\n");
|
threadCreate("Test1", (cpu_kstate_function_arg1_t *)kthread1, (void *)"Hlowrd\n");
|
||||||
kthreadMsleep(1000);
|
threadMsleep(1000);
|
||||||
kthreadCreate("wq timeout", wqThread, NULL);
|
threadCreate("wq timeout", wqThread, NULL);
|
||||||
kthreadMsleep(2000);
|
threadMsleep(2000);
|
||||||
assert(haveTimeout);
|
assert(haveTimeout);
|
||||||
kthreadCreate("sleep", sleepThread, NULL);
|
threadCreate("sleep", sleepThread, NULL);
|
||||||
kthreadMsleep(5000);
|
threadMsleep(5000);
|
||||||
kthreadCreate("mtest1", mutThread, "mut1");
|
threadCreate("mtest1", mutThread, "mut1");
|
||||||
kthreadCreate("mtest2", mutThread, "mut2");
|
threadCreate("mtest2", mutThread, "mut2");
|
||||||
kthreadCreate("mtest3", mutThread, "mut3");
|
threadCreate("mtest3", mutThread, "mut3");
|
||||||
}
|
}
|
||||||
|
|
||||||
void testATAThread(){
|
void testATAThread(){
|
||||||
@ -365,7 +365,7 @@ void testATAThread(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void testATA(){
|
static void testATA(){
|
||||||
kthreadCreate("ATA_TEST", testATAThread, NULL);
|
threadCreate("ATA_TEST", testATAThread, NULL);
|
||||||
//testATAThread();
|
//testATAThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user