Fix ghost threads in CPU

* kernel: Make sf9 return TSTATE_FREE for invalid slots: 0, >255, free.
* menu: Ignore free slots even if other fields of proc_info look valid.
        Documentation (sysfuncs.txt) clearly states all the other info
        as invalid when slot_state is TSTATE_FREE.
* taskbar: Same as menu.
* cmm/lib/*: Same as menu.
* programs/macros.inc: Add TSTATE_* macros.
This commit is contained in:
2025-02-01 02:53:14 +00:00
parent 6933ee64cd
commit d235c8914c
6 changed files with 39 additions and 28 deletions

View File

@@ -2320,23 +2320,16 @@ sys_cpuusage:
jne .no_who_am_i jne .no_who_am_i
mov ecx, [current_slot_idx] mov ecx, [current_slot_idx]
.no_who_am_i: .no_who_am_i:
jecxz .empty_slot ; default value for (slot == 0) and (slot > 255)
mov [ebx+process_information.slot_state], TSTATE_FREE
test ecx, ecx
jz .nofillbuf
cmp ecx, max_processes cmp ecx, max_processes
ja .empty_slot ja .nofillbuf
mov edx, ecx mov edx, ecx
shl edx, BSF sizeof.APPDATA shl edx, BSF sizeof.APPDATA
cmp [SLOT_BASE+edx+APPDATA.state], TSTATE_FREE cmp [SLOT_BASE+edx+APPDATA.state], TSTATE_FREE
jnz .thread_found jz .nofillbuf
.empty_slot:
; zero buffer for an empty slot
push edi
xor eax, eax
mov edi, ebx
movi ecx, sizeof.process_information
rep stosb
pop edi
jmp .nofillbuf
.thread_found:
; +4: word: position of the window of thread in the window stack ; +4: word: position of the window of thread in the window stack
mov ax, [WIN_STACK + ecx * 2] mov ax, [WIN_STACK + ecx * 2]
mov [ebx+process_information.window_stack_position], ax mov [ebx+process_information.window_stack_position], ax

View File

@@ -79,6 +79,7 @@ dword I_Path = #__path;
#define CLOSE_BTN 1 #define CLOSE_BTN 1
#define TSTATE_FREE 9
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#include "../lib/system.h" #include "../lib/system.h"

View File

@@ -15,10 +15,12 @@ enum {
:bool CheckProcessExists(dword proc_name) { :bool CheckProcessExists(dword proc_name) {
int i; int i;
proc_info Process; proc_info Process;
for (i=0; i<MAX_PROCESS_COUNT; i++;) for (i=0; i<MAX_PROCESS_COUNT; i++)
{ {
GetProcessInfo(#Process, i); GetProcessInfo(#Process, i);
if (strcmpi(#Process.name, proc_name)==0) return 1; if (Process.status_slot != TSTATE_FREE)
&& (strcmpi(#Process.name, proc_name)==0)
return 1;
} }
return 0; return 0;
} }
@@ -26,10 +28,11 @@ enum {
:void KillProcessByName(dword proc_name, byte multiple) { :void KillProcessByName(dword proc_name, byte multiple) {
int i; int i;
proc_info Process; proc_info Process;
for (i=0; i<MAX_PROCESS_COUNT; i++;) for (i=0; i<MAX_PROCESS_COUNT; i++)
{ {
GetProcessInfo(#Process, i); GetProcessInfo(#Process, i);
if (strcmpi(#Process.name, proc_name)==0) if (Process.status_slot != TSTATE_FREE)
&& (strcmpi(#Process.name, proc_name)==0)
{ {
KillProcess(Process.ID); KillProcess(Process.ID);
if (multiple==SINGLE) break; if (multiple==SINGLE) break;
@@ -40,10 +43,12 @@ enum {
:int GetProcessesCount(dword proc_name) { :int GetProcessesCount(dword proc_name) {
int i, count=0; int i, count=0;
proc_info Process; proc_info Process;
for (i=0; i<MAX_PROCESS_COUNT; i++;) for (i=0; i<MAX_PROCESS_COUNT; i++)
{ {
GetProcessInfo(#Process, i); GetProcessInfo(#Process, i);
if (strcmpi(#Process.name, proc_name)==0) count++; if (Process.status_slot != TSTATE_FREE)
&& (strcmpi(#Process.name, proc_name)==0)
count++;
} }
return count; return count;
} }
@@ -57,7 +62,7 @@ enum {
int i; int i;
proc_info Process, Self; proc_info Process, Self;
GetProcessInfo(#Self, -1); GetProcessInfo(#Self, -1);
for (i=0; i<MAX_PROCESS_COUNT; i++;) for (i=0; i<MAX_PROCESS_COUNT; i++)
{ {
GetProcessInfo(#Process, i); GetProcessInfo(#Process, i);
if (Process.name) if (Process.name)

View File

@@ -450,6 +450,15 @@ struct BOX
height dd ? height dd ?
ends ends
; Thread states:
TSTATE_RUNNING = 0
TSTATE_RUN_SUSPENDED = 1
TSTATE_WAIT_SUSPENDED = 2
TSTATE_ZOMBIE = 3
TSTATE_TERMINATING = 4
TSTATE_WAITING = 5
TSTATE_FREE = 9
; structures used in KolibriOS ; structures used in KolibriOS
struct process_information struct process_information
cpu_usage dd ? ; +0 cpu_usage dd ? ; +0
@@ -461,7 +470,7 @@ struct process_information
used_memory dd ? ; +26 used_memory dd ? ; +26
PID dd ? ; +30 PID dd ? ; +30
box BOX ; +34 box BOX ; +34
slot_state dw ? ; +50 slot_state dw ? ; +50 TSTATE_*
dw ? ; +52 dw ? ; +52
client_box BOX ; +54 client_box BOX ; +54
wnd_state db ? ; +70 wnd_state db ? ; +70

View File

@@ -783,13 +783,14 @@ align 4
.loop: .loop:
push ecx push ecx
mcall 9,procinfo mcall 9,procinfo
cmp word[ebx+50], TSTATE_FREE
je @f
mov eax,[menu_mame] mov eax,[menu_mame]
cmp [ebx+10],eax cmp [ebx+10],eax
jne @f jne @f
; temporary to fit into 3 IMG sectors mov ax,[menu_mame+4]
;mov ax,[menu_mame+4] cmp [ebx+14],ax
;cmp [ebx+14],ax jne @f
;jne @f
cmp ecx,[active_process] cmp ecx,[active_process]
je @f je @f
; dph ecx ; dph ecx

View File

@@ -28,6 +28,8 @@ align 4
need_window_tab: need_window_tab:
; in: ebx->process info ; in: ebx->process info
; out: ZF set <=> do not draw ; out: ZF set <=> do not draw
cmp byte [ebx + process_information.slot_state], TSTATE_FREE
jz .nodraw
cmp byte [ebx + process_information.process_name], '@' cmp byte [ebx + process_information.process_name], '@'
jz .nodraw jz .nodraw
; do not draw undefined (zero-sized) windows ; do not draw undefined (zero-sized) windows