Rename kthread to thread

This commit is contained in:
Mathieu Maret 2021-10-30 14:18:21 +02:00
parent ca4b318df6
commit e65a57d55d
11 changed files with 129 additions and 127 deletions

View File

@ -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] = {

View File

@ -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);

View File

@ -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();
} }

View File

@ -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
View 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);

View File

@ -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;

View File

@ -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;

View File

@ -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,11 +191,11 @@ 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
@ -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()

View File

@ -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

View File

@ -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);
} }

View File

@ -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();
} }