Messages in this thread |  | | From | Mark.Hemment@uniplex ... | Date | Thu, 1 Aug 96 09:51:53 +0100 | Subject | LWPs (was:Re: proc fs and shared pids) |
| |
Hi,
It's been a few years since I looked (and messed) around with threads, so forgive any errors I make. The below is given as food for thought...
As I remember, there are 3 basic types of threads; o Kernel Thread (basically for _kernel_ processes) o Light Weight Process (what I'm interrested in here) o User Level Thread
clone() tries to give Linux LWPs. Basically, this involves allocating and setting up a _new_ task struct, and referencing some other structures (signal handlers, etc) from the clone()ing process. I would say this is the _wrong_ way round.
The new thread should use the _old_ task struct, and allocate memory for the state which it does not want to share with the cloning process. This could be achieved with a new structure 'thread struct', which contains the thread's state. An incomplete list of what would be in the thread struct; o Kernel Stack o Saved Registers (inc. FPU) o Signal Mask o An alternative signal stack (sigaltstack()) o Ptr back to task struct o Scheduling pri o I'm sure there's more....
'thread structures' would be doubly-linked off the task struct, with (obviously) at least one thread per task. Threads would be the unit of scheduling and context switching. On entering the kernel, the globals 'current' and 'thread' would be set to the entering task struct and thread struct respectively. A task only 'dies' when _all_ it's threads have exited.
All threads within a task _share_ the same pid. This _isn't_ a major restriction. Signals are split into two groups; exceptions and interrupts. An exeception is a signal generated by a thread due to its direct actions, such as; SIGILL, SIGSEGV. An exception is delievered to the thread which generated the execption. Interrupts (which are any signals that are not exceptions) are delievered to any thread within the task which is not ignoring the signal. When signals are used for inter-task communication, the sending task _shouldn't_ care about what thread receives the signal. Signals should not be used for inter-thread communication within a thread - there are much better inter-commun. methods for threads. Note: threads would share their signal handlers, but not their signal masks.
Sharing the task struct among threads does cause one problem, with fork(). Should fork() create a new task which contains only the calling thread? Or should it create a new task containing all the threads in the parent task? The answer depends on why the thread is forking, and the solution (as Solarias, I believe) is to have two forks - one for each case.
Under '/proc/pid' would be the 'normaly' files that contain the task info, and a sub-directory for each thread in the task.
OK, I've missed a lot out, but this is the basic idea. Comments?
markhe
|  |