diff --git a/sys/kern/kern_rtprio.pas b/sys/kern/kern_rtprio.pas index 88dddf54..4f62d760 100644 --- a/sys/kern/kern_rtprio.pas +++ b/sys/kern/kern_rtprio.pas @@ -127,42 +127,11 @@ begin thread_dec_ref(td1); end; -procedure _for_lookup_rtprio(td:p_kthread;rtp:p_rtprio); register; //Tfree_data_cb -var - _rtp2:t_rtprio; -begin - if (td=nil) or (rtp=nil) then Exit; - - pri_to_rtp(td,@_rtp2); - if (_rtp2._type$FFFF) then - begin - err:=rtp_to_pri(rtp,td); - if (err<>0) then - begin - rtp^._type:=$FFFF; - rtp^._prio:=err; - end; - end; -end; - function sys_rtprio(func,pid:Integer;rtp:p_rtprio):Integer; var - td:p_kthread; - _rtp:t_rtprio; + td,tdp:p_kthread; + rtp1,rtp2:t_rtprio; + i:kthread_iterator; begin if (pid<>0) and (pid<>g_pid) then Exit(ESRCH); @@ -170,41 +139,78 @@ begin if (func=RTP_SET) then begin - Result:=copyin(rtp,@_rtp,sizeof(t_rtprio)) + Result:=copyin(rtp,@rtp1,sizeof(t_rtprio)) end else begin Result:=0; - _rtp:=Default(t_rtprio); + rtp1:=Default(t_rtprio); end; case func of RTP_LOOKUP: begin + + PROC_LOCK; + if (pid=0) then begin - pri_to_rtp(td,@_rtp); + pri_to_rtp(td,@rtp1); end else begin - _rtp._type:=RTP_PRIO_IDLE; - _rtp._prio:=RTP_PRIO_MAX; - FOREACH_THREAD_IN_PROC(@_for_lookup_rtprio,@_rtp); + rtp1._type:=RTP_PRIO_IDLE; + rtp1._prio:=RTP_PRIO_MAX; + + if FOREACH_THREAD_START(@i) then + begin + repeat + tdp:=THREAD_GET(@i); + + pri_to_rtp(tdp,@rtp2); + + if (rtp2._type0) then Exit; + + PROC_LOCK; + if (pid=0) then begin - Result:=rtp_to_pri(@_rtp,td); + Result:=rtp_to_pri(@rtp1,td); end else begin - FOREACH_THREAD_IN_PROC(@_for_set_rtprio,@_rtp); - if (_rtp._type=$FFFF) then + + if FOREACH_THREAD_START(@i) then begin - Result:=_rtp._prio; + repeat + tdp:=THREAD_GET(@i); + + Result:=rtp_to_pri(@rtp1,tdp); + if (Result<>0) then Break; + + until not THREAD_NEXT(@i); + FOREACH_THREAD_FINISH(); end; + end; + + PROC_UNLOCK; end; else Result:=EINVAL; diff --git a/sys/kern/kern_sig.pas b/sys/kern/kern_sig.pas index 158ac54a..4cdfa573 100644 --- a/sys/kern/kern_sig.pas +++ b/sys/kern/kern_sig.pas @@ -404,30 +404,25 @@ begin sigqueue_delete_set(sq,@_set); end; -type - p_t_sdsp=^_t_sdsp; - _t_sdsp=record - worklist:p_sigqueue; - _set:p_sigset_t - end; - -procedure _for_sdsp(td:p_kthread;data:p_t_sdsp); register; //Tfree_data_cb -begin - sigqueue_move_set(@td^.td_sigqueue,data^.worklist,data^._set); -end; - procedure sigqueue_delete_set_proc(_set:p_sigset_t); var + td0:p_kthread; worklist:sigqueue_t; - data:_t_sdsp; + i:kthread_iterator; begin sigqueue_init(@worklist); sigqueue_move_set(@g_p_sigqueue,@worklist,_set); - data.worklist:=@worklist; - data. _set:=_set; + if FOREACH_THREAD_START(@i) then + begin + repeat + td0:=THREAD_GET(@i); - FOREACH_THREAD_IN_PROC(@_for_sdsp,@data); + sigqueue_move_set(@td0^.td_sigqueue,@worklist,_set); + + until not THREAD_NEXT(@i); + FOREACH_THREAD_FINISH(); + end; sigqueue_flush(@worklist); end; @@ -1325,34 +1320,12 @@ begin PROC_UNLOCK; end; -type - p_t_sigtd=^_t_sigtd; - _t_sigtd=record - first_td:p_kthread; - signal_td:p_kthread; - sig:Integer - end; - -procedure _for_sigtd(td:p_kthread;data:p_t_sigtd); register; //Tfree_data_cb -begin - if (td=nil) or (data=nil) then Exit; - - if (data^.first_td=nil) then - begin - data^.first_td:=td; - end; - - if (data^.signal_td=nil) then - if (not SIGISMEMBER(@td^.td_sigmask,data^.sig)) then - begin - data^.signal_td:=td; - end; -end; - function sigtd(sig,prop:Integer):p_kthread; var td:p_kthread; - data:_t_sigtd; + first_td :p_kthread; + signal_td:p_kthread; + i:kthread_iterator; begin td:=curkthread; @@ -1362,17 +1335,35 @@ begin Exit(td); end; - data:=Default(_t_sigtd); - data.sig:=sig; + first_td :=nil; + signal_td:=nil; - FOREACH_THREAD_IN_PROC(Pointer(@_for_sigtd),@data); - - if (data.signal_td=nil) then + if FOREACH_THREAD_START(@i) then begin - Result:=data.first_td; + repeat + td:=THREAD_GET(@i); + + if (first_td=nil) then + begin + first_td:=td; + end; + + if (not SIGISMEMBER(@td^.td_sigmask,sig)) then + begin + signal_td:=td; + Break; + end; + + until not THREAD_NEXT(@i); + FOREACH_THREAD_FINISH(); + end; + + if (signal_td=nil) then + begin + Result:=first_td; end else begin - Result:=data.signal_td; + Result:=signal_td; end; end; diff --git a/sys/kern/kern_thread.pas b/sys/kern/kern_thread.pas index f2be81d9..141cfbef 100644 --- a/sys/kern/kern_thread.pas +++ b/sys/kern/kern_thread.pas @@ -19,6 +19,10 @@ uses kern_rtprio, hamt; +type + p_kthread_iterator=^kthread_iterator; + kthread_iterator=THAMT_Iterator32; + function thread_alloc:p_kthread; procedure thread_free(td:p_kthread); @@ -42,7 +46,11 @@ procedure thread_dec_ref(td:p_kthread); procedure thread_lock(td:p_kthread); procedure thread_unlock(td:p_kthread); function tdfind(tid:DWORD):p_kthread; -procedure FOREACH_THREAD_IN_PROC(cb,userdata:Pointer); + +function FOREACH_THREAD_START(i:p_kthread_iterator):Boolean; +procedure FOREACH_THREAD_FINISH(); +function THREAD_NEXT(i:p_kthread_iterator):Boolean; +function THREAD_GET(i:p_kthread_iterator):p_kthread; function SIGPENDING(td:p_kthread):Boolean; @@ -232,15 +240,34 @@ begin end; end; -procedure FOREACH_THREAD_IN_PROC(cb,userdata:Pointer); +function FOREACH_THREAD_START(i:p_kthread_iterator):Boolean; begin rw_wlock(tidhash_lock); - HAMT_traverse32(@tidhashtbl,Tfree_data_cb(cb),userdata); + Result:=HAMT_first32(@tidhashtbl,i); + if not Result then //space + begin + rw_wunlock(tidhash_lock); + end; +end; + +procedure FOREACH_THREAD_FINISH(); +begin rw_wunlock(tidhash_lock); end; +function THREAD_NEXT(i:p_kthread_iterator):Boolean; +begin + Result:=HAMT_next32(i); +end; + +function THREAD_GET(i:p_kthread_iterator):p_kthread; +begin + Result:=nil; + HAMT_get_value32(i,@Result); +end; + function BaseQueryInfo(td:p_kthread):Integer; var TBI:THREAD_BASIC_INFORMATION; @@ -571,35 +598,18 @@ begin // NOTREACHED end; -type - p_t_stk=^_t_stk; - _t_stk=record - error:Integer; - sig:Integer; - td:p_kthread; - ksi:ksiginfo_t; - end; - -procedure _for_stk(td:p_kthread;data:p_t_stk); register; //Tfree_data_cb -begin - if (td<>data^.td) then - begin - data^.error:=0; - if (data^.sig=0) then Exit; - tdksignal(td,data^.sig,@data^.ksi); - end; -end; - function sys_thr_kill(id,sig:Integer):Integer; var - data:_t_stk; + td,ttd:p_kthread; + ksi:ksiginfo_t; + i:kthread_iterator; begin - data.td:=curkthread; + td:=curkthread; - ksiginfo_init(@data.ksi); - data.ksi.ksi_info.si_signo:=sig; - data.ksi.ksi_info.si_code :=SI_LWP; - data.ksi.ksi_info.si_pid :=g_pid; + ksiginfo_init(@ksi); + ksi.ksi_info.si_signo:=sig; + ksi.ksi_info.si_code :=SI_LWP; + ksi.ksi_info.si_pid :=g_pid; if (id=-1) then //all begin @@ -608,19 +618,31 @@ begin Result:=EINVAL; end else begin - data.error:=ESRCH; - data.sig:=0; + Result:=ESRCH; PROC_LOCK; - FOREACH_THREAD_IN_PROC(@_for_stk,@data); + + if FOREACH_THREAD_START(@i) then + begin + repeat + ttd:=THREAD_GET(@i); + if (ttd<>td) then + begin + Result:=0; + if (sig=0) then Break; + tdksignal(ttd,sig,@ksi); + end; + until not THREAD_NEXT(@i); + FOREACH_THREAD_FINISH(); + end; + PROC_UNLOCK; - Result:=data.error; end; end else begin Result:=0; - data.td:=tdfind(DWORD(id)); - if (data.td=nil) then Exit(ESRCH); + td:=tdfind(DWORD(id)); + if (td=nil) then Exit(ESRCH); if (sig=0) then begin @@ -629,9 +651,9 @@ begin if (not _SIG_VALID(sig)) then Result:=EINVAL else - tdksignal(data.td,sig,@data.ksi); + tdksignal(td,sig,@ksi); - thread_dec_ref(data.td); + thread_dec_ref(td); end; end; diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index 6c3c9c23..88658fd5 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -444,12 +444,12 @@ begin if (tid<>curkthread^.td_tid) then begin - test_files; - Writeln('[--test_dirs--]'); - test_dirs('','/',1); - Writeln('[--test_dirs--]'); - - readln; + //test_files; + //Writeln('[--test_dirs--]'); + //test_dirs('','/',1); + //Writeln('[--test_dirs--]'); + // + //readln; tid2:=curkthread^.td_tid;