Review Question
Consider the Program
#include <stdio.h>
int main(){
putchar('X');
exit(0);
}
Suppose it is compiled an an a.out file is generated. now suppose that a user in a local console window types a.out and hits the return key. what happens? be sure to describe a plausible but detailed and comprehensive sequence of operating system actions and events, not just what the user sees.
My answer
First, the shell will create a process in User Space
Then it will perform the system call 'putchar' Which simulates input, and the process will switch to kernel mode
It will then add the process (thread) to the long term scheduler where it will join the set of all processes that are ready to run
Once it is selected, it will move to the short term scheduler, where it will receive some processing time (ready -> running)
Since this process is an IO bound process, it will then head to the IO queue, where it will be stored in a buffer where it awaits execution (running -> waiting)
Once the IO is complete, the putchar call will print the X on the peripheral for which it is applied (the monitor) (waiting -> running)
Once the process returns to the short term scheduler it will again receive more processing time. Since there is nothing left to do but terminate, the process terminates (running -> terminated)
Is this valid understanding? Am I missing some critical concepts for process creation? I know it is relatively simple process, but please advise anything I am missing.
Thanks for reading, and thanks in advance for assistance.
First, the shell will create a process in User Space
// A lot of things happen before this!!
//The program will be loaded by the loaded.
//VM areas will be created for this process.
//Linking for library files will be done.
//Then a series of pagefault will occur will happen to bring your file on physical and virtual memory
Then it will perform the system call 'putchar' Which simulates input, and the process will switch to kernel mode
//putchar in not at all a system call!!!!
//putchar will call its library implementation, which will further call a write() system call and your program will get trapped inside the kernel
It will then add the process (thread) to the long term scheduler where it will join the set of all processes that are ready to run
//Totally depends upon the scheduling algorithms.. might be possible your process will be first to run!!
Once it is selected, it will move to the short term scheduler, where it will receive some processing time (ready -> running)
//Right, waiting on RunQ
Since this process is an IO bound process, it will then head to the IO queue, where it will be stored in a buffer where it awaits execution (running -> waiting)
//Sort of, it will be waiting on I/O queue, waiting for an interrupt, to write on o/p device
Once the IO is complete, the putchar call will print the X on the peripheral for which it is applied (the monitor) (waiting -> running)
//Correct
Once the process returns to the short term scheduler it will again receive more processing time. Since there is nothing left to do but terminate, the process terminates (running -> terminated)
//Before this it will again get trapped inside the kernel when your program will execute RETURN statement.
//It will call the back the startup function which was responsible for calling the main() function.
//Then startup() function will return 0 to operating system, and hence OS will kill this process and moce it to terminated state..
I still don't think its a complete version as 100's of machine instruction will be executed for this program and its difficult to pin point each and everyone..
But, still if you have some doubt post your comment!!]
Hope this will help!!!
Related
Let's say I want to execute the following commands:
cmd_buff start
dispatch (write to texture1)
copy (texture1 on gpu to buffer1 host-visible)
dispatch (write to texture2)
cmd_buff end
I'd like to know as soon as possible when buffer1's data are available.
My idea here is to have a waiting thread on which I'd wait for the copy to have completed. What I'd do is first split the above list of cmds into:
cmd_buff_1 start
dispatch (write to texture1)
copy (texture1 on gpu to buffer1 host-visible)
cmd_buff_1 end
and:
cmd_buff_2 start
dispatch (write to texture2)
cmd_buff_2 end
Now, I'd call vkQueueSubmit with cmd_buff_1 and with some fence1, followed by a call to another vkQueueSubmit with cmd_buff_2 with NULL fence.
On the waiting thread I'd call vkWaitForFences( fence1 ).
That's how I see such an operation. However, I'm wondering if that is optimal and if there was actually any way to put a direct sync still within cmd_buff_1 so that I wouldn't need to split the cmd buffer into two?
Never break up submit operations just to test fences; submit operations are too heavyweight to do that. If the CPU needs to check to see if work on the GPU has reached a specific point, there are many options other than a fence.
The simplest mechanism for something like this is to use an event. Set the event after the transfer operation, then use vkGetEventStatus on the CPU to see when it is ready. That's a polling function, so a waiting CPU thread won't immediately wake up when the data is ready (but then, there's no guarantee that would happen with a non-polling function either).
If timeline semaphores are available to you, you can wait for them to reach a particular counter value on the CPU with vkWaitSemaphores. This requires that you break the batch up into two batches, but they can both be submitted in the same submit command.
I have two JVM processes A and B. Process A communicates with the user and uses B as a slave, to do heavy computation: User -> A -> B.compute
Yet the method B.compute can run out of memory for certain inputs (it is impossible to know which). In such case I want to inform the user, that the input data he gave me is not appropriate, and I want to restart B.
I found the following (not very detailed) solutions on google:
catch the error in B catch (OutOfMemoryException e)
use JVM option -XX:OnOutOfMemoryError=restart-command
manually restart B from A
Which method is the most appropriate to use?
Please show a minimal (OS agnostic) working example.
Letting the JVM terminate abruptly is never a good design for any kind of application.
If you know that there are situations that will cause this, I would design process B to monitor its own memory usage and then terminate processing of data if it is going to run out of memory.
You can do this as simply as:
Runtime rt = Runtime.getRuntime();
long usedMem = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024;
You could set a threshold on free memory where your B process will stop processing the input, throw away all results and inform A that this is an erroneous input. The garbage collector will reclaim unused memory and return B to being ready for more input (if you really have to you could make an explicit call to System.gc() to force this but I wouldn't recommend it).
I have a question about the following diagram from Operating Systems Concepts: http://unboltingbinary.in/wp-content/uploads/2015/04/image028.jpg
This diagram seems to imply that after every I/O operation, the process is placed back on the ready queue before being sent to the CPU again. However, is it possible for a process to terminate after I/O but before being sent to the ready queue?
Suppose we have a program that computes a number and then writes it to storage. In this case, does the process really need to return to the CPU after the I/O operation? It seems to me that the process should be allowed to terminate right after I/O. That way, there would be no need for a context switch.
Once one process has successfully executed a termination request on another, the threads of the terminated process should never run again, no matter what state they were in - blocked on I/O, blocked on inter-thread comms, running on a core, sleeping, whatever - they all must be stopped immediately if running and all be put in a state where they will never run again.
Anything else would be a security issue - terminated threads should not be given execution at all, (else it may not be possible to terminate the process).
Process termination requires the cpu. Changes to kernel mode structures on process exit, returning memory resources, etc. all require the cpu.
A process simply just does not evaporate. The term you want here is process rundown - I think.
As OS concepts book illustrate this section "Process States":
Process has defined states: new, ready, running, waiting and terminated.
I have conflict between new and ready states, I know that in ready state the process is allocated in memory and all resources needed at creation time is allocated but it is only waiting for CPU time (scheduling).
But what is the new state? what is the previous stage before allocating it in memory?
All the tasks that the OS has to perform cannot be allocated memory immediately after the task is submitted to the OS. So they have to remain in the new state. The decision as to when they move to the ready state is taken by the Long term scheduler. More info about long term scheduler here http://en.wikipedia.org/wiki/Scheduling_(computing)#Long-term_scheduling
To be more precise,the new state is for those processes which are just being created.These haven't been created fully and are in it's growing stage.
Whereas,the ready state means that the process created which is stored in PCB(Process Control Block) has got all the resources which it required for execution,but CPU is not running that process' instructions,
I am giving you a simple example :-
Say, you are having 2 processes.Process A is syncing your data over cloud storage and Process B is printing other data.
So,in case process B is getting created to be stored in PCB,the other
process,Process A has been already created and is not getting the
chance to run because CPU hasn't called these instructions of Process
A.But,Process B requires printer to be found and other drivers to be
checked.It must also check for verification of pages to be printed!
So,here Process A has been created and is waiting for
CPU-time---hence,in ready state. Whereas,Process B is waiting for
printer to be initialised and files to be examined to be
printed--->Hence,in new state(That means these processes haven't been
successfully added into PCB).
One more thing to guide you isFor each process there is a Process Control Block, PCB, which stores the process-specific information.
I hope it clears your doubt.Feel free to comment whatever you don't understand...
Would like to know how the scheduler gets called so that it can switch tasks. As in even if its preemptive scheduling or round robin scheduling - the scheduler should come in to picture to do any kind of task switching. Supposing a low priority task has an infinite loop - when does the scheduler intervene and switch to a higher priority task?
Query is:
1. Who calls the scheduler? [in VxWorks]
2. If it gets called at regular intervals - how is that mechanism implemented?
Thanks in advance.
--Ashwin
The simple answer is that vxWorks takes control through a hardware interrupt from the system timer that occurs continually at fixed intervals while the system is running.
Here's more detail:
When vxWorks starts, it configures your hardware to generate a timer interrupt every n milliseconds, where n is often 10 but completely depends on your hardware. The timer interval is generally set up by vxWorks in your Board Support Package (BSP) when it starts.
Every time the timer fires an interrupt, the system starts executing the timer interrupt handler. The timer interrupt handler is part of vxWorks, so now vxWorks has control. The first thing it does is save the CPU state (such as registers) into the Task Control Block (TCB) of the currently running task.
Then eventually vxWorks runs the scheduler to determine who runs next. To run a task, vxWorks copies the state of the task from its TCB into the machine registers, and after it does that the task has control of the CPU.
Bonus info:
vxWorks provides hooks into the task switching logic so you can have a function get called whenever your task gets preempted.
indiv provides a very good answer, but it is only partially accurate.
The actual working of the system is slightly more complex.
The scheduler can be executed as a result of either synchronous or asynchronous operations.
Synchronous refers to operations that are caused as a result of the code in the currently executing task. A prime example of this would be to take a semaphore (semTake).
If the semaphore is not available, the currently executing task will pend and no longer be available to execute. At this point, the scheduler will be invoked and determine the next task that should execute and will perform a context switch.
Asynchronous operations essentially refer to interrupts. Timer interrupts were very well described by indiv. However, a number of different elements could cause an interrupt to execute: network traffic, sensor, serial data, etc...
It is also good to remember that the timer interrupt does not necessarily cause a context switch! Yes, the interrupt will occur, and delayed task and the time slice counters will be decremented. However, if the time slice is not expired, or no higher priority task transitions from the pended to the ready state, then the scheduler will not actually be invoked, and you will return back to the original task, at the exact point where execution was interrupted.
Note that the scheduler does not have its own context; it is not a task. It is simply code that executes in whatever context it is invoked from. Either from the interrupt context (asynchronous) or from the invoking task context (synchronous).
Unless you have a majorily-customized target build, the scheduler is invoked by the Timer interrupt. Details are platform-specific, though.
The scheduler also gets invoked if current task gets completed or blocks.