smp: proper cleanup on (non-main) thread exit
This commit is contained in:
parent
240e01d69c
commit
20bc9f4a64
@ -39,10 +39,11 @@ static inline int minmax(int val, int min, int max) {
|
|||||||
|
|
||||||
static SYSV_ABI void kThreader(int a, int b, int c, int d, int e, int f) {
|
static SYSV_ABI void kThreader(int a, int b, int c, int d, int e, int f) {
|
||||||
io_Printf("kThreader: args[%d,%d,%d,%d,%d,%d]\n", a, b, c, d, e, f);
|
io_Printf("kThreader: args[%d,%d,%d,%d,%d,%d]\n", a, b, c, d, e, f);
|
||||||
for (;;) {
|
for (int i = 0; i < 10; i++) {
|
||||||
smp_thread_Sleep(768);
|
|
||||||
io_Printf("kThreader: Not sleeping!\n");
|
io_Printf("kThreader: Not sleeping!\n");
|
||||||
|
smp_thread_Sleep(768);
|
||||||
}
|
}
|
||||||
|
io_Printf("kThreader: byebye!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "kthread_switch.h"
|
#include "kthread_switch.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include "../runtime/panic_assert.h"
|
||||||
#include "../util/tree.h"
|
#include "../util/tree.h"
|
||||||
#include "../interrupt/interrupt.h"
|
#include "../interrupt/interrupt.h"
|
||||||
#include "../driver/irq/pic/rtc/rtc.h"
|
#include "../driver/irq/pic/rtc/rtc.h"
|
||||||
@ -10,6 +11,23 @@
|
|||||||
#include "../memory/paging_internal.h"
|
#include "../memory/paging_internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
// defined in assembly
|
||||||
|
SYSV_ABI void __smp_thread_EntryPoint();
|
||||||
|
|
||||||
|
// for __smp_thread_EntryPoint cleanups
|
||||||
|
// assumes interrupt is disabled
|
||||||
|
SYSV_ABI NORETURN void __smp_thread_Cleanup() {
|
||||||
|
__smp_Thread *t = __smp_Current[0];
|
||||||
|
tree_Delete(__smp_Threads, tree_FindNode(__smp_Threads, t->id));
|
||||||
|
__smp_Current[0] = 0;
|
||||||
|
|
||||||
|
// Now that we're pretending to be a idle thread, this should not return
|
||||||
|
// thread_Switch() sets the interrupt flag on idle for us
|
||||||
|
smp_thread_Yield();
|
||||||
|
Panic("__smp_thread_Cleanup: Yield not switching to another thread");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
smp_thread_ID smp_thread_Init() {
|
smp_thread_ID smp_thread_Init() {
|
||||||
INTERRUPT_DISABLE;
|
INTERRUPT_DISABLE;
|
||||||
__smp_Threads = tree_Create(sizeof(__smp_Thread));
|
__smp_Threads = tree_Create(sizeof(__smp_Thread));
|
||||||
@ -51,8 +69,9 @@ smp_thread_ID smp_thread_Start(void *entry, const smp_thread_Arguments *args, un
|
|||||||
|
|
||||||
t->state.cs = GDT_EXEC_SELECTOR;
|
t->state.cs = GDT_EXEC_SELECTOR;
|
||||||
t->state.ss = 0;
|
t->state.ss = 0;
|
||||||
t->state.rip = (uint64_t)entry;
|
t->state.rip = (uint64_t)__smp_thread_EntryPoint;
|
||||||
|
|
||||||
|
t->state.rax = (uint64_t)entry;
|
||||||
t->state.rdi = args->a;
|
t->state.rdi = args->a;
|
||||||
t->state.rsi = args->b;
|
t->state.rsi = args->b;
|
||||||
t->state.rdx = args->c;
|
t->state.rdx = args->c;
|
||||||
|
19
smp/kthread_asm.S
Normal file
19
smp/kthread_asm.S
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
format elf64
|
||||||
|
|
||||||
|
extrn __smp_thread_Cleanup
|
||||||
|
public __smp_thread_EntryPoint
|
||||||
|
|
||||||
|
|
||||||
|
; sysvx64abi void __smp_thread_EntryPoint(uintptr_t a,b,c,d,e,f)
|
||||||
|
;
|
||||||
|
; Calls thread entry point in RAX, and, after it returns,
|
||||||
|
; removes the current thread from the structure.
|
||||||
|
section '.text' executable
|
||||||
|
__smp_thread_EntryPoint:
|
||||||
|
call rax
|
||||||
|
|
||||||
|
; Thread returned; delete the current thread
|
||||||
|
; The current thread: In __smp_Threads, not in __smp_ThreadsWaiting
|
||||||
|
|
||||||
|
cli ; Disable interrupt on thread structure operations
|
||||||
|
jmp __smp_thread_Cleanup ; This will not return
|
Loading…
Reference in New Issue
Block a user