Killing the process, those threads that are ready or running

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
OSwhatever
Member
Member
Posts: 595
Joined: Mon Jul 05, 2010 4:15 pm

Killing the process, those threads that are ready or running

Post by OSwhatever »

When you are killing your process, how do you deal with those threads that are already running or in some scheduler in ready state? Do you actively try to find and seek up those threads and remove them from the scheduler queue, do you mark them as dead and discard them during rescheduling?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Killing the process, those threads that are ready or run

Post by Combuster »

You will want to have a list of threads per process for bookkeeping anyway. Clearing up a thread that's not running simply involves removing it from any process queue it's in and deleting the data. The only tricky part is when a thread calls for a kill on itself, which makes it easiest to just suspend the process as a whole and then have a kernel thread clean it up (which also saves you from problems caused by deleting page directories that are in use), and notify the caller when it's done
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Killing the process, those threads that are ready or run

Post by Gigasoft »

When you terminate a process, you terminate all threads belonging to that process, except for the current one, then the current thread is also terminated if it belongs to the process being terminated.

Terminating the current thread typically involves putting it on a finished list, and then stopping. When terminating a running thread that is not the current one, it must be interrupted (through an IPI, or waiting for it to end up in an interrupt on its own). A thread that is being terminated from another thread should stop instead of returning to user mode. One can also terminate a ready thread directly, as long as it is known that it is not inside a system call. Things are slightly complicated if the system performs nested user mode calls. Then, all threads has to be terminated in the same way: Instead of returning to user mode, it should return to the previous kernel mode function, if any, and otherwise it should mark itself as finished and stop.

If a thread is waiting, the wait should be canceled if possible, especially a wait that is initiated by the user or something that could take a long time.

A system thread should be woken up whenever a thread finishes, and it should then free any resources associated with the thread, after checking that it is not still running (if it is, it should try again later).
OSwhatever
Member
Member
Posts: 595
Joined: Mon Jul 05, 2010 4:15 pm

Re: Killing the process, those threads that are ready or run

Post by OSwhatever »

What I've understand from what you've have written, if the thread was previously blocked in the kernel, resume and kill it before jumping back to user mode. If the thread was not blocked in the kernel, you can kill it directly when it turns up by the scheduler. Hunting threads inside the scheduler is perhaps not a good idea since the state can change pretty quickly in an SMP environment as I previously thought.
xyzzy
Member
Member
Posts: 391
Joined: Wed Jul 25, 2007 8:45 am
Libera.chat IRC: aejsmith
Location: London, UK
Contact:

Re: Killing the process, those threads that are ready or run

Post by xyzzy »

I don't allow killing of other threads that are running in the kernel. Instead, I set a flag on the thread to say that it is killed. If the thread is in interruptible sleep it is woken, or if it tries to go into interruptible sleep it just returns an interrupted error immediately. Then, just before the return to user mode, the killed flag is tested, and if it is set it will exit there.
rdos
Member
Member
Posts: 3310
Joined: Wed Oct 01, 2008 1:55 pm

Re: Killing the process, those threads that are ready or run

Post by rdos »

Interesting topic. I currently have no mechanism for killing threads or processes in my OS, but I have thought about how to do it. Part of the problem is that most threads will be waiting for some type of event in kernel-space, or might own some resource that other threads needs (either a kernel resource or some user level resource). Because I have no solutions for these problems, I haven't implemented killing threads. Part of the problem is that I don't want to associate resources with threads.

What I would need to handle is to kill threads as exit() is called in a process. This is simpler as it can discard the problem with threads that have acquired resources in user space, and only needs to gracefully exit event-waits, and release kernel locks / resources. Since kernel resources are allocated per-process (using a handle scheme), all these resources are automatically deleted as the process exists.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Killing the process, those threads that are ready or run

Post by xenos »

I have two functions named "ExitThread" and "ExitProcess" in my task scheduler class. Their purpose is to exit either the current process or the current threat, so they are pure "suicide" functions. (I have not implemented killing a different process / thread yet.) When they are invoked, they simply mark the current thread / process as dead and ask the scheduler to switch to the per-cpu idle thread.

The real work is done in the scheduler. After the actual thread switch has been done, the scheduler checks whether the previously running thread should be deleted - either because it has terminated or because its owner process has terminated. In that case the thread is removed. Otherwise, it is inserted into the run queue. Similarly, the threads that are retrieved from the run queue are checked whether they are actually dead and should be deleted. Finally, when the last thread of a process has been deleted, the process itself is deleted.

The logic behind this mechanism is that dead running threads are deleted as soon as their timeslice expires and the switch to a new thread has been done. This guarantees that the thread is not using and any processor - which means that no processor is executing its code or using its kernel stack, so both can be deleted safely. When a process is deleted, none of its threads is running anymore, so finally its address space can safely be deleted.

I have not yet implemented any wait states, so "running", "ready" and "dead" are currently the only states I need to consider. The whole thing will certainly become more complex as soon as I need to consider wait states as well... Further my processes do not hold any resources besides their address space, so as soon as I implemented resource handling, process deletion will become a bit more complex, too.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Post Reply