Process state kept in PCB and thread state kept in TCB - operating-system

Assume process p0 has been created. P0 has two threads (main thread) t0 and t1. So somewhere there is PCB0 for p0, TCB0 for t0 and TCB1 for t1.
(5 execution states for simplicity: created, ready, running, blocked, terminated)
The p0 is in running state when at least one of it's threads is in running state?
For sure in TCB there must be a field for thread state. If the p0 state can be directly calculated from the state of it's threads: Is there a field of execution state in PCB and why?
If the answer in 2 is yes: Each time a thread state is changing do we have to check the state of all process' threads in order to keep the PCB.state up to date? This isn't redundant?

The p0 is in running state when at least one of it's threads is in
running state?
Not everytime. Process state and thread state can be different. So it is not necessary when thread is in running p0 remains in running it can be in block or ready state. Some of the possible situation between thread and process :
The process is in ready state, one of the process’s threads is in running state.
The process is blocked in blocked state, one of the process’s threads is in running state.
e.g. when threaded application starts as a process containing single thread . At that time process is in running state. Then application uses user level thread library to create additional threads. Now when thread A begins to run it will enter the running state.Suppose Thread A make an I/O system call . In this situation control is transferred to the kernel which blocks the process .In this case thread A is still in running , even though the process is in blocked state. This is one of the example when process is blocked but thread is running.
For sure in TCB there must be a field for thread state.
yes there is field for state(e.g running , terminate , ready , block etc ) in tcb.
Is there a field of execution state in PCB and why?
Yes there is field of state in PCB too. But it is not calculated from tcb state because as I told both state can be different. Thread will generally call different procedures and thus a different execution history.
Hope you satisfy with my answer . Good luck :-)
---> Check this link for reference
---> check link for content of TCB and PCB

Related

What happens to a process and/or thread while it waits on a mutex?

When a process and/or thread waits on mutex in which state the process and/or thread is? Is it in WAIT or READY or some other state? I tried to search the answer over the web but could not find a clear, definitive answer, maybe there isn't one or maybe there is, to find out that I am posting this question here.
tl;dr: Nothing happens when it is waiting; it is simply a kernel data structure.
Without loss of generality, all operating systems have some sort of model where a unit of execution (task) moves between the states : Ready, Running, Waiting. This Task has a data structure associated with it, where its state and registers (among other things) are recorded.
When a task moves from Ready to Running, its saved registers are loaded on a cpu, and it continues execution from its last saved state. Initially, its saved registers are set to reasonable values for the program to start.
From Running to Waiting or Ready, its registers are stored in its task data structure, and this structure is placed on either a list of Ready or Waiting tasks.
From Waiting to Ready, the task data structure is removed from the Waiting list and appended to the Ready list.
When a task tries to acquire a mutex that is unavailable, it moves from Running (how else could it try to get the mutex) to Waiting. If the mutex was available, it remains Running, and the mutex becomes unavailable.
When a task releases a mutex, and another task is Waiting for that mutex, the Waiting task becomes Ready, and acquires the mutex. If many tasks are Waiting, one is chosen to acquire the mutex and become Ready, the rest remain Waiting.
This is a very abstract description; real systems are complicated by both a plurality of synchronization mechanisms (mailbox, queue, semaphore, pipe, ...), a desire to optimise the various paths, and the utilization of multiple CPUs.

Test and set lock(TSL) are deadlock free?

The concept of priority inversion is a case when TSL cannot be deadlock free then how one can say the TSL is deadlock free?
Lets first look at the definition of Deadlock.
Definition :- A set of processes are said to be in Deadlock, if they wait for happening of event caused by other processes in the same set. Here the processes in the set are in waiting/blocked state.
Now lets understand the Priority Inversion. Lets process A is a lower priority process running in critical section. and process B be higher priority process.
When the process B goes to ready state,it gets scheduled (goes to running state) and process A gets pre-empted by schedular as it has low priority. Here Process A goes to waiting/blocked state but it has already locked the critical section and process B is in running state which then goes in Busy waiting because the critical section is already locked by process A !!. This causes an infinite waiting. This case is basically called as SpinLock since process B is in running state and process A is in waiting/blocked state but according to definition of Deadlock all process should be in waiting/blocked state.
This is why TSL is said to be Deadlock free but its NOT free from SpinLock.
I hope this will be helpful :)

How scheduler knows a Task is in blocking state?

I am reading "Embedded Software Primer" by David E.Simon.
In it discusses RTOS and its building blocks Scheduler and Task. It says each Task is either in Ready State, Running State, or Blocking State. My question is how the scheduler determines a Task is in Blocking State? Assume it's waiting for a Semaphore. Then it likely Semaphore is in a state it can't return. Does Scheduler see if a function does not return, then mark its state as Blocking?
The implementation details will vary by RTOS. Generally, each task has a state variable that identifies whether the task is ready, running, or blocked. The scheduler simply reads the task's state variable to determine whether the task is blocked.
Each task has a set of parameters that determine the state and context of the task. These parameters are often stored in a struct and called the "task control block" (although the implementation varies by RTOS). The ready/run/block state variable may be a part of the task control block.
When the task attempts to get the semaphore and the semaphore is not available then the task will be set to the blocked state. More specifically, the semaphore-get function will change the task from running to blocked. And then the scheduler will be called to determine which task should run next. The scheduler will read through the task state variables and will not run those tasks that are blocked.
When another task eventually sets the semaphore then the task that is blocked on the semaphore will be changed from the blocked to the ready state and the scheduler may be called to determine if a context switch should occur.
As I'm writing a RTOS ( http://distortos.org/ ), I thought that I may chime in.
The variable which holds the state of each thread is indeed usually implemented in RTOSes, and this includes mine version:
https://github.com/DISTORTEC/distortos/blob/master/include/distortos/ThreadState.hpp#L26
https://github.com/DISTORTEC/distortos/blob/master/include/distortos/internal/scheduler/ThreadControlBlock.hpp#L329
However this variable usually is used only as a debugging aid or for additional checks (like preventing you from starting a thread that is already started).
In RTOSes targeted at deeply embedded systems the distinction between ready/blocked is usually made using the containers that hold the threads. Usually the threads are "chained" in linked lists, usually also sorted by priority and insertion time. The scheduler has its own list of threads that are "ready" ( https://github.com/DISTORTEC/distortos/blob/master/include/distortos/internal/scheduler/Scheduler.hpp#L340 ). Each synchronization object (like a semaphore) also has its own list of threads which are "blocked" waiting for this object ( https://github.com/DISTORTEC/distortos/blob/master/include/distortos/Semaphore.hpp#L244 ) . When a thread attempts to use a semaphore that is currently not available, it is simply moved from the scheduler's "ready" list to semaphores's "blocked" list ( https://github.com/DISTORTEC/distortos/blob/master/source/synchronization/Semaphore.cpp#L82 ). The scheduler doesn't need to decide anything, as now - from scheduler's perspective - this thread is just gone. When this semaphore is now released by another thread, first thread which was waiting on this semaphore's "blocked" list is moved back to scheduler's "ready" list ( https://github.com/DISTORTEC/distortos/blob/master/source/synchronization/Semaphore.cpp#L39 ).
Usually there's no need to make special distinction between threads that are ready and the thread that is actually running. As the amount of threads that can actually run is fixed and equal to the number of available CPU cores, then all you need is a pointer for each CPU core which points to the thread from the "ready" list which is running at that core at that moment. In my system I do the same - the thread that is at the head of the "ready" list is the one that is running, but I also manage an iterator which points to that thread ( https://github.com/DISTORTEC/distortos/blob/master/include/distortos/internal/scheduler/Scheduler.hpp#L337 ). You could have a separate list for running threads, but in most cases it would be a waste of space (there's usually just one) and makes other things slightly more complicated.
I've actually wrote an article about thread states and their transitions if you're interested - http://distortos.org/documentation/task-states/ This article has no special distinction between the thread that is "ready" and the one that is actually running. I don't consider this distinction to be actually useful for anything, as long as you have other means to tell which of the "ready" threads is running.

how to terminate an infinitely running process

this question was asked to me in NVIDIA interview
Q)if a process is running from infinite time and O.S. has completely lost control on it, then how would you deallocate resources from that process?
This is a very open question for which the answer depends on lot of factors like signal mechanism of the OS, fork wait exit are implemented, states in which a process can be ...etc. Your answers should have been on the following lines.
A process can be in 1 of these states: ready, running, waiting.. apart from this there is born state and terminated/zombie state. During its lifetime i.e after fork() till exit(), a process has system resources under its control. Ex:entries in process table, open files to IO devices, VM allocated, mappings in page table etc...
OS has lost complete control of the process: I interpret as follows--
----- A process can execute a system call Ex-read and the OS will put the process into sleep/waiting state. There are 2 kinds of sleep: INTERRUPTIBLE & UNINTERRUPTIBLE
After the read is done the Hardware sends a signal to the OS which will get redirected to the sleeping process. And the process will spring up to action again. There may also be a case where the read never completed so the Hardware never sent a signal.
Assume the process initiated a read (which will fail) and went to a:
a INTERRUPTIBLE SLEEP: Now the OS/parent of this process can send a SIGSTOP, SIGKILL etc to this process and it will be interrupted from its sleep and then the OS can kill the process reclaim all the resources. This is fine and solves your problem of infinite resource control.
b UNINTERRUPTIBLE SLEEP: Now even though the read has not sent any signal, but is taking infinite time, and the parent/OS knows that the read has failed likely sending SIGSTOP,SIGKILL has no effect since it is sleeping UNITERRUPTIBLY waiting for read to finish. So now the process has control over system resource and OS cant claim it back. See this for clear understanding of UNITERRUPTIBLE SLEEP. So, if a process is in this state from an infinite time, the OS or parent CANNOT kill/stop it and reclaim the resource, those resources are tied indefinitely and can be reclaimed only when the system is powered off, or you need to hack the driver where a service is struck and get it terminated by the driver which will then send the read failed signal to UNINTERRUPTIBLE PROCESS.
----- after the process has completed its execution and ready to die, the parent which created this process has not yet called wait on this child and process is in ZOMBIE state, in which case it is still hanging on to some system resources. Usually it is the job of the parent to ensure that the child it created terminates normally. But, it may be the case that the parent which was supposed to call wait on this child itself got killed, then the onus of terminating this child goes to the OS, that is exactly what init process does on UNIX like OSes. Apart from its other jobs, init acts like a foster parent for the process whoes parent are dead. It runs the check_ZOMBIE procedures every now and then ( when system resources are low) to ensure that ZOMBIES dont hang on to system resources.
From the wikipedia article : When a process loses its parent, init becomes its new parent. Init periodically executes the wait system call to reap any zombies with init as parent. One of init's responsibilities is reaping orphans and parentless zombies.
So your answer should be pointing at the way process states are defined, signal handling mechanisms are implemented and also the way init process reaps ZOMBIES etc ....
Hope it cleared a thing or two..
Cheers....

Terminology about thread

If a function in a thread is going to return, how can we describe this behavior.
The thread returns.
The thread is dying.
What's the meaning of "thread is dead"?
In my understanding, threads are basically kernel data structures. You can create and destroy threads through the system APIs. If you just create a thread, start it executing, and it runs out of code, the kernel will probably put it into a non-executing state. In unmanaged code you still have to release that resource.
Then there's the thread pool. In that case, you queue up work to be done by the thread pool, and the platform takes care of picking a thread and executing your work. When the work is complete, the thread is returned to the thread pool. The platform takes care of creating and destroying threads to balance the available threads against the workload and the system resources.
As of Java 1.3 the six-state thread model was introduced. This includes the following states:
Ready-to-run: The thread is created and waiting for being picked for running by the thread scheduler
Running: The thread is executing.
Waiting: The thread is in blocked state while waiting for some external processing to finish (like I/O).
Sleeping: The thread is forced to sleep via .sleep()
Blocked: On I/O: Will move into state 1 after finished (e.g. reading a byte of data). On sync: Will move into state 1 after a lock is acquired.
Dead (Terminated): The thread has finished working and cannot be resumed.
The term "Dead" is rarely used today, almost totally changed to "Terminated". These two are equivalent.
Most thread APIs work by asking the operating system to run a particular function, supplied by you, on your behalf. When this function eventually returns (via for example a return statement or reaching the end of its code) the operationg system ends the thread.
As for "dead" threads - that's not a term I've seen used in thread APIs.