What is preemptive multitasking? - multitasking

What is preemptive multitasking? After googling it I couldn't find an answer can someone help me?

http://en.wikipedia.org/wiki/Preemption_(computing)
Read the Wikipedia article. Think of it this way, it is a way to allow you to run many different programs at once without each program needing to have been written to give up the processor's time - the OS handles it. The idea is that each process is "preempted" at some point.

simply if a process is a preemptive then it can be stopped and send to ready queue by external interruption(trap).
When a process switches from the running state to the waiting state (for example, as the result of an I/O request or an invocation of wait() for the termination of a child process)
When a process switches from the running state to the ready state (for example, when an interrupt occurs)
When a process switches from the waiting state to the ready state (for example, at completion of I/O)
When a process terminates
For situations 1 and 4,there is not-preemptive

Preemptive Multitasking requires two main components: A timer interrupt ( say every 10 msec ) and a scheduler which is 'Connected' to that interrupt. The scheduler then saves the 'context' of the "interrupted/preempted" task ( which is fancy term for all the registers/stack pointer) in some area ( like stack) and then determines via its scheduling algorithm which ( other) task can "run" next.
If it finds one, it unwinds/restores the context for THAT task and returns from the timer interrupt. BTW, just like a "call" which places the return address ( usually the address after the Call instruction on the stack, an interrupt works the same way and when an interrupt "returns" it uses what is on the stack an jumps to it. So when we're returning from some other task to its 'interrupt' point we just have to manipulate the stack, and place the return address from THAT task on the TOP of the stack and do an "Return-from_Interrupt" instruction. Different from normal return. I bet you're now sorry you asked !
Cheers,

Related

When a process makes a system call to transmit a TCP packet over the network, which of the following steps do NOT occur always?

I am teaching myself OS by going through the lecture notes of the course at IIT Bombay (https://www.cse.iitb.ac.in/~mythili/os/). One of the questions in the Process worksheet asks which of the following doesn't always happen in the situation described at the title. The answer is C.
A. The process moves to kernel mode.
B. The program counter of the CPU shifts to the kernel part of the address space.
C. The process is context-switched out and a separate kernel process starts execution.
D. The OS code that deals with handling TCP/IP packets is invoked
I'm a bit confused though. I thought when an interrupt routine occurs the process is context-switched out so other processes can run and the CPU is not idle during that time. The kernel, then, will take care of the packet sending. Why would C not be correct then?
You are right in saying that "when an interrupt routine occurs the process is context-switched out so other processes can run and the CPU is not idle during that time", but the words "generally or mostly" need to be added to it.
In most cases, there is another process waiting for CPU time and that can be scheduled. However it is not the case 100% of the time. The question is about the word "always" and while other options always occur in the given situation, option C is a choice that OS makes at run time. If OS determines that switching out this process can be sub optimal than performing the system call and resuming the same process, then it may not perform the context switching.
There is a cost associated with context switching and if other processes are also blocked on some I/O then it may be optimal for OS to NOT switch the context or there might be other reasons to not switch the context such as what if only 1 process is running, there is no other process to switch the context to!

How does the FreeRTOS kernel suspend a task on Arduino UNO?

There is a FreeRTOS library for Arduino, purported to even run on the UNO.
I'm trying to understand the inner workings of how a multi-tasking operating system can run on such limited hardware. I understand the principles of task scheduling/switching, but how does the kernel actually suspend a task in order to execute another one? How does it interrupt (and then later resume) the currently-executing code?
My guess is that a scheduled ISR (timer) directly modifies the stack to change the instruction pointer, but if it does this, it needs to make a copy of the stack and registers before switching tasks, then restore the current task's stack/registers before resuming execution. I'm not clear on how it would do this.
Can the FreeRTOS kernel switch tasks in the middle of, for example, a Serial.println() function call, (or any call that doesn't include cli()) and if so, how does it do this?
Thanks for any clarification.
My guess is that a scheduled ISR (timer) directly modifies the stack to change the instruction pointer, but if it does this, it needs to make a copy of the stack and registers before switching tasks, then restore the current task's stack/registers before resuming execution. I'm not clear on how it would do this.
Your guess is correct. If you look at port.c you will see, that the FreeRTOS makros portSAVE_CONTEXT and portRESTORE_CONTEXT are pushes respective pops all registers of the current running task to perform the task switch. Furthermore the watchdog timer interrupt is used to run the scheduler.
As long this watchdog timer is enabled and is triggerd, task switches can happen any time. So a switch can also happen during any function call like Serial.println. This implies that if you call this function from several task you will sooner or later corrupt your output of the serial stream.

How does async task interrupt main thread (from itself - the main one)?

I can't seem to find this specific implementation detail, or even a pointer to where in an OS book to find this.
Basically, main thread calls an async task (to be run later) on itself. So... when does it run?
Does it wait for the run loop to finish? Or does it just randomly interrupt the run-loop in the middle of any function?
I understand the registers will be the same (unless separate thread), but not really the instruction pointer and what happens to the stack, if anything does happen.
Thank you
In C# the task is scheduled to be run on the current SynchronizationContext. The context basically has a queue of tasks which it schedules to run on the threads it is associated with, in a GUI app there is only one thread so the task is scheduled to run there.
The GUI thread is not interrupted but it executes the task when it finishes all other tasks preceding it in the queue.
The threads of a process all share the same address space, not the same CPU registers. The thread scheduling is done depends on the programming language and the O/S. Usually there are explicit scheduling points, such as returning from a system call, blocking awaiting I/O completion, or between p-code instructions for interpreted languages. Some O/S implemtations reschedule depending on how long a thread has run for time-based scheduling. Often languages include a function that explicitly offers the CPU to any other thread or process by transferring control to the process or thread scheduler component of the O/S.
The act of switching from one thread or process to another is known as a context switch and is carefully tuned code because this is often done thousands of times per second. This can make the code difficult to follow.
The best explanation of this I've ever seen is http://www.amazon.com/The-Design-UNIX-Operating-System/dp/0132017997 classic.

Cooperative Multitasking system

I'm trying to get around the concept of cooperative multitasking system and exactly how it works in a single threaded application.
My understanding is that this is a "form of multitasking in which multiple tasks execute by voluntarily ceding control to other tasks at programmer-defined points within each task."
So if you have a list of tasks and one task is executing, how do you determine to pass execution to another task? And when you give execution back to a previous task, how do resume from where you were previously?
I find this a bit confusing because I don't understand how this can be achieve without a multithreaded application.
Any advice would be very helpeful :)
Thanks
In your specific scenario where a single process (or thread of execution) uses cooperative multitasking, you can use something like Windows' fibers or POSIX setcontext family of functions. I will use the term fiber here.
Basically when one fiber is finished executing a chunk of work and wants to voluntarily allow other fibers to run (hence the "cooperative" term), it either manually switches to the other fiber's context or more typically it performs some kind of yield() or scheduler() call that jumps into the scheduler's context, then the scheduler finds a new fiber to run and switches to that fiber's context.
What do we mean by context here? Basically the stack and registers. There is nothing magic about the stack, it's just a block of memory the stack pointer happens to point to. There is also nothing magic about the program counter, it just points to the next instruction to execute. Switching contexts simply saves the current registers somewhere, changes the stack pointer to a different chunk of memory, updates the program counter to a different stream of instructions, copies that context's saved registers into the CPU, then does a jump. Bam, you're now executing different instructions with a different stack. Often the context switch code is written in assembly that is invoked in a way that doesn't modify the current stack or it backs out the changes, in either case it leaves no traces on the stack or in registers so when code resumes execution it has no idea anything happened. (Again, the theme: we assume that method calls fiddle with registers, push arguments to the stack, move the stack pointer, etc but that is just the C calling convention. Nothing requires you to maintain a stack at all or to have any particular method call leave any traces of itself on the stack).
Since each stack is separate, you don't have some continuous chain of seemingly random method calls eventually overflowing the stack (which might be the result if you naively tried to implement this scheme using standard C methods that continuously called each other). You could implement this manually with a state machine where each fiber kept a state machine of where it was in its work, periodically returning to the calling dispatcher's method, but why bother when actual fiber/co-routine support is widely available?
Also remember that cooperative multitasking is orthogonal to processes, protected memory, address spaces, etc. Witness Mac OS 9 or Windows 3.x. They supported the idea of separate processes. But when you yielded, the context was changed to the OS context, allowing the OS scheduler to run, which then potentially selected another process to switch to. In theory you could have a full protected virtual memory OS that still used cooperative multitasking. In those systems, if a errant process never yielded, the OS scheduler never ran, so all other processes in the system were frozen. **
The next natural question is what makes something pre-emptive... The answer is that the OS schedules an interrupt timer with the CPU to stop the currently executing task and switch back to the OS scheduler's context regardless of whether the current task cares to release the CPU or not, thus "pre-empting" it.
If the OS uses CPU privilege levels, the (kernel configured) timer is not cancelable by lower level (user mode) code, though in theory if the OS didn't use such protections an errant task could mask off or cancel the interrupt timer and hijack the CPU. There are some other scenarios like IO calls where the scheduler can be invoked outside the timer, and the scheduler may decide no other process has higher priority and return control to the same process without a switch... And in reality most OSes don't do a real context switch here because that's expensive, the scheduler code runs inside the context of whatever process was executing, so it has to be very careful not to step on the stack, to save register states, etc.
** You might ask why not just fire a timer if yield isn't called within a certain period of time. The answer lies in multi-threaded synchronization. In a cooperative system, you don't have to bother taking locks, worry about re-entrance, etc because you only yield when things are in a known good state. If this mythical timer fires, you have now potentially corrupted the state of the program that was interrupted. If programs have to be written to handle this, congrats... You now have a half-assed pre-emptive multitasking system. Might as well just do it right! And if you are changing things anyway, may as well add threads, protected memory, etc. That's pretty much the history of the major OSes right there.
The basic idea behind cooperative multitasking is trust - that each subtask will relinquish control, of its own accord, in a timely fashion, to avoid starving other tasks of processor time. This is why tasks in a cooperative multitasking system need to be tested extremely thoroughly, and in some cases certified for use.
I don't claim to be an expert, but I imagine cooperative tasks could be implemented as state machines, where passing control to the task would cause it to run for the absolute minimal amount of time it needs to make any kind of progress. For example, a file reader might read the next few bytes of a file, a parser might parse the next line of a document, or a sensor controller might take a single reading, before returning control back to a cooperative scheduler, which would check for task completion.
Each task would have to keep its internal state on the heap (at object level), rather than on the stack frame (at function level) like a conventional blocking function or thread.
And unlike conventional multitasking, which relies on a hardware timer to trigger a context switch, cooperative multitasking relies on the code to be written in such a way that each step of each long-running task is guaranteed to finish in an acceptably small amount of time.
The tasks will execute an explicit wait or pause or yield operation which makes the call to the dispatcher. There may be different operations for waiting on IO to complete or explicitly yielding in a heavy computation. In an application task's main loop, it could have a *wait_for_event* call instead of busy polling. This would suspend the task until it has input to process.
There may also be a time-out mechanism for catching runaway tasks, but it is not the primary means of switching (or else it wouldn't be cooperative).
One way to think of cooperative multitasking is to split a task into steps (or states). Each task keeps track of the next step it needs to execute. When it's the task's turn, it executes only that one step and returns. That way, in the main loop of your program you are simply calling each task in order, and because each task only takes up a small amount of time to complete a single step, we end up with a system which allows all of the tasks to share cpu time (ie. cooperate).

What is a signal in Unix?

This comment confuses me: "kill -l generally lists all signals". I thought that a signal means a quantized amount of energy.
[Added] Please, clarify the (computational) signal in Unix and the physical signal. Are they totally different concepts?
[Added] Are there major differences between paradigms? Is the meaning the same in languages such as C, Python and Haskell? The signal seems to be a general term.
I cannot believe that people are not comparing things such as hardware and software or stressing OS at some points.
Comparison between a signal and an interrupt:
The difference is that while
interrupts are sent to the operating
system by the hardware, signals are
sent to the process by the operating
system, or by other processes. Note
that signals have nothing to do with
software interrupts, which are still
sent by the hardware (the CPU itself,
in this case). (source)
Definitions
process = a program in execution, according to the book below
Further reading
compare the signal to Interrupts and Exceptions
Tanenbaum's book Modern Operating Systems
The manual refers to a very basic mechanism that allow processes or the operation system to notify other processes by sending a signal. The operation system can use it to notify programs about abortions of them (signal SIGABRT) or about a segmentation fault (often caused by accessing a null-pointer, SIGSEGV), to name two of them.
Some unix servers use signals so the administrator can use kill to send them a signal, causing them to re-read their configuration file, without requiring them to restart.
There are default actions taken for some signals and other signals are just ignored. For example on receive of a SIGSEGV, the program terminates, while receiving a SIGCHLD, meaning a child-process died, will by default result in nothing special.
There is a ANSI C standard function that installs a signal handler, which is a function that can execute some code when receiving a signal, called signal (read in man signal). In different unix's, that function behave different, so its usage is discouraged. Its manpage refers to the sigaction function (read man sigaction), which behaves consistent, and is also more powerful.
A physical signal and a Unix signal are indeed different concepts. When a Unix signal is sent from one process to another, there is no specific corresponding physical signal. Unix signals are merely an abstraction so programmers can talk about processes communicating with one another.
Unix signals could have been called messages, events, notifications, or even a made-up term like "frobs". The designers just chose the name "signal", and it stuck.
A signal is a message, either to the target process, or to the OS about the target process. It is part of the unix API (and is defined in various POSIX standards).
Read man kill, man signal, and man sigaction.
Other SO questions that might be helpful:
What is the difference between sigaction and signal?
Some from my notes :
Allows asynchronous communication
Between processes belonging to the
same user
From the system to any process
From the system manager to any process
All associated information is in the signal itself
Many different signals
SIGINT
From the system to all processes
associated to a terminal
Trigger: ^C pressed
Usual way to stop a running process
SIGFPE
From the kernel to a single process
Trigger: error in floating point operation
SIGKILL
To a single process
Stops the execution of the destination process
SIGALRM
From the kernel to a single process
Trigger: timer expiration
SIGTERM
To a single process
Recommends the process to terminate gracefully
SIGUSR1, SIGUSR2
From any process to any other
Without a predefined semantic
Freely usable by programmers
Sending a signal to another process
int kill(pid, signal_ID)
The programmer can decide what to do when a signal
is received
Use the default behavior
Ignore it
Execute a user function
Detecting an interrupted write
if (write(fd, buff, SIZE)<0) {
switch (errno) {
case EINTR:
warning(“Interrupted write\n”);
break;
}
}…
A signal is a message which can be sent to a running process.
For example, to tell the Internet Daemon (inetd) to re-read its configuration file, it should be sent a SIGHUP signal.
For example, if the current process ID (PID) of inetd is 1234, you would type:
kill -SIGHUP 1234
A signal is "an event, message, or data structure transmitted between computational processes" (from Wikipedia).
In this case signal means 'message'. So it's sending a message to a process which can tell the process to do various things.
A unix signal is a kind of message that can be sent to and from unix processes. They can do things like tell a process to quit (SIGKILL) or that a process had an invalid memory reference (SIGSEGV) or that the process was killed by the user hitting control-c (SIGINT).
from a *nix command line type in:
man signal
that will should you all the signals available.
Signal is basically an interrupt that tells the process that a particular event has happened.
Signal generally send by the kernel, meanwhile a process can also send the signal to other process (depends on permission ans all ) by using kill and killall command and a process can send signal to itself by using raise.
Major use of signal:
To handle the interrupt.
Process synchronization.
Signal is an interrupt that used to intimate a process that a particular event has happened.
Signal can be send by kernel to running process or one process to another process.
In bash kill and killall command used to send the signal.

Resources