diff --git a/sys/kern_thread.pas b/sys/kern_thread.pas index dffaf5bf..0c6aebb9 100644 --- a/sys/kern_thread.pas +++ b/sys/kern_thread.pas @@ -187,8 +187,8 @@ procedure thread_unlock(td:p_kthread); function tdfind(tid:DWORD):p_kthread; procedure FOREACH_THREAD_IN_PROC(cb,userdata:Pointer); -function curkthread:p_kthread; assembler; -procedure set_curkthread(td:p_kthread); assembler; +function curkthread:p_kthread; +procedure set_curkthread(td:p_kthread); function SIGPENDING(td:p_kthread):Boolean; inline; function TD_IS_RUNNING(td:p_kthread):Boolean; inline; @@ -816,7 +816,7 @@ begin Result:=cpu_set_priority(td,prio); end; -procedure sched_prio(td:p_kthread;prio:Integer); inline; +procedure sched_prio(td:p_kthread;prio:Integer); begin td^.td_base_pri:=prio; sched_priority(td, prio); diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index 8bfc33d0..c82597ec 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -149,7 +149,9 @@ begin //SetTlsBase(Pointer(qword(1))); - sleep(1); + sig_lock; + sleep(1); + sig_unlock; Writeln('GetTlsBase:',HexStr(GetTlsBase)); @@ -595,7 +597,7 @@ begin _thr_param.rtp :=@prio; _thr_param.name :='test'; - sys_thr_new(@_thr_param,SizeOf(_thr_param)); + thr_new(@_thr_param,SizeOf(_thr_param)); //readln; diff --git a/sys/thr.pas b/sys/thr.pas index b3994997..ecf43608 100644 --- a/sys/thr.pas +++ b/sys/thr.pas @@ -30,10 +30,16 @@ implementation uses trap; -function thr_new(param:p_thr_param;param_size:Integer):Integer; assembler; nostackframe; -asm - movq sys_thr_new,%rax - call fast_syscall +function thr_new(param:p_thr_param;param_size:Integer):Integer; +begin + if (curkthread=nil) then + begin + Result:=sys_thr_new(param,param_size); + end else + asm + movq sys_thr_new,%rax + call fast_syscall + end; end; function thr_self(id:PQWORD):Integer; assembler; nostackframe; @@ -41,6 +47,7 @@ asm movq sys_thr_self,%rax call fast_syscall end; + procedure thr_exit(state:PQWORD); assembler; nostackframe; asm movq sys_thr_exit,%rax diff --git a/sys/trap.pas b/sys/trap.pas index 0fed30fc..ee319af6 100644 --- a/sys/trap.pas +++ b/sys/trap.pas @@ -91,6 +91,11 @@ const PCB_FULL_IRET=1; procedure set_pcb_flags(td:p_kthread;f:Integer); + +procedure sig_lock; +procedure _sig_unlock; +procedure sig_unlock; + procedure fast_syscall; implementation @@ -99,6 +104,45 @@ uses vm_machdep, kern_sig; +const + NOT_PCB_FULL_IRET=not PCB_FULL_IRET; + TDF_AST=TDF_ASTPENDING or TDF_NEEDRESCHED; + +procedure sig_lock; assembler; nostackframe; +asm + pushf + lock incl %gs:(0x710) //lock interrupt + popf +end; + +procedure _sig_unlock; assembler; nostackframe; +asm + pushf + lock decl %gs:(0x710) //unlock interrupt + popf +end; + +procedure sig_unlock; +var + td:p_kthread; + count:Integer; +begin + asm + pushf + lock decl %gs:(0x710) //unlock interrupt + popf + movl %gs:(0x710),%eax + movl %eax,count + end; + if (count=0) then + begin + td:=curkthread; + if (td=nil) then Exit; + if (td^.td_flags and TDF_AST)=0 then Exit; + ast; + end; +end; + procedure set_pcb_flags(td:p_kthread;f:Integer); inline; begin td^.pcb_flags:=f; @@ -134,10 +178,6 @@ begin cpu_set_syscall_retval(td,error); end; -const - NOT_PCB_FULL_IRET=not PCB_FULL_IRET; - TDF_AST=TDF_ASTPENDING or TDF_NEEDRESCHED; - procedure fast_syscall; assembler; nostackframe; label _after, @@ -301,18 +341,6 @@ asm //restore rip end; -//testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax) -//2: /* AST scheduled. */ -//sti -//movq %rsp,%rdi -//call ast -//jmp 1b -// -//3: /* Requested full context restore, use doreti for that. */ -//MEXITCOUNT -//jmp doreti - -