Is ISR or mutex task has the higher priority? - mutex

is it possible for an ISR to occur during mutex task is running, actually what I want to know is whether mutex task or ISR has the higher priority?

This depends entirely on the OS and the mutex implementation. Typical mutex APIs contain a trylock(). There are versions of trylock() which can be used in an interrupt service routine (ISR). However, as an ISR services hardware and they must always execute. There is no way to block the execution with a mutex. Instead, the hardware can be turned off so there are no interrupts or interrupts can be masked. Masking the interrupts is frond upon as it will increase interrupt latency; Ie, you can cause hardware issues.
It is a really bad idea for a general user task to block all system interrupts. If this is what you wish, you probably have an issue with your design.

Related

Can Context Switching happens between ISRs?

I am still a new learner in this field and appreciate anyone who can give me some opinions.
Let me introduce the situation of my problem:
1.The keyboard interrupt occurs when Process A is executing. As far as I know, it doesn't matter if Process A was executing in user mode or kernel mode. The Interrupt Handler will be invoked to deal with the keyboard interrupt in kernel mode.
2.The Interrupt Handler will save the state of Process A in its kernel stack and executes the ISR corresponding to the keyboard interrupt(still using the kernel stack of Process A).
3.During the execution of the keyboard ISR, the clock interrupt occurs. Then the interrupts will be nested.
4.The Interrupt Handler will save the state of the keyboard ISR in the kernel stack of Process A and executes the ISR corresponding to the clock interrupt(still using the kernel stack of Process A).
5.The clock ISR updates the system time and finishes. But os finds out the time slice of Process A has been used up.
Question:
1.What will the os do next?
Will the os schedule another process first Or will the os finish the keyboard ISR first? I prefer the former because the state of the interrupted keyboard ISR is saved in the kernel stack of Process A. It can be restored when Process A is selected to run after some time. Am I right?
2.Is there any difference in interrupt handling between common os(like Linux) and real time os?
Unfortunately there is no single answer to this question. The exact behavior depends on the interrupt controller implementation, if the OS supports Symmetric multi processing(SMP) and the specific scheduler.
The interrupt controller implementation is important because some processors do not support nested ISRs while some do. CPUs that do not supported nested interrupts are going to return to kernel operation after servicing an interrupt. If multiple interrupts are triggered in a narrow time window so servicing overlaps, typically the CPU will enter kernel mode very briefly and then return back to an interrupt context to handle the next interrupt. If nested interrupts are supported then the typical behavior is for the CPU to stay in the interrupt context until the "stack" of interrupts is serviced before returning to a kernel context.
The OS supporting SMP is also very important to the exact behavior of interrupt handling. When SMP is supported, it possible, and probably very likely, that the another core may be scheduled to handle the kernel and subsequent user space workload to handle what ever the interrupt trigged. Suppose the ISR served a Ethernet port on core 1, upon completion of the ISR, core 1 could service another interrupt, while core 2 wakes up and runs the user process waiting on the network traffic from the ethernet port.
To add a final wrinkle of complexity, interrupts can typically be routed to different CPUs, the exact way dependent on the interrupt controller implementation. This is done to minimize interrupt latency by keeping all the interrupts from pilling up on one CPU waiting for the sequential handling.
Finally, typical scheduler implementations don't track the ISR servicing time when calculating time slices for a given thread. As for the difference in handling between a traditional fair scheduler or an RTOS, there generally are not significant differences. Ultimately its the interrupt controller hardware that dictates the order interrupts are handled in, not the software's thread scheduler.

Why Disabling Interrupts Synchronization Satisfies Bounded Waiting

Definition: Bounded waiting refers to a process P_i that keeps waiting forever to enter critical section (CS) while other processes P_j keep entering CS although P_i has shown interest to enter CS.
Now, I understand why lock variable mechanism is not bounded waiting because if a process entered a non-critical section, then another process might come and take CS, so a process might starve.
Algorithm:
NCS (Non-critical Section)
DISABLE INTERRUPTS
CS
ENABLE INTERRUPTS
NCS
Edit: no more details are given about schedulers, etc. The question is to get a glance whether this satisfies bounded waiting or not.
Question: can you please explain why disabled interrupts synchronization mechanism satisfies bounded waiting please (a process can not starve to enter CS as in lock variable mechanism)?
Your question has two contexts to consider:
Are interrupt handlers entering the Critical Section?
Is there an asynchronous scheduler involved?
No,No
As soon as P_i releases the CS, the release mechanism can accept P_j, thus starvation is averted.
No,Yes
Despite P_j's desire, once interrupts are released, the scheduler could be invoked, and decide that P_j is not to be executed next, so in at least a pathological case, could spend forever trying to enter the CS while others are selected.
Yes,No
As soon as P_i release the interrupt, any pending interrupts will execute immediately. If they are to enter the CS, they will first (otherwise the system has halted [*]), so with the right timing a set of interrupts could keep P_j starved forever.
Yes,Yes
Here, the starvation could happen for either of the reasons No,Yes or Yes,No.
[*] - Interrupts have no a-priori way of deferring work, so any resources required to complete the interrupt handler must be available when the handler runs. The handlers context is effectively nested; and a nested context cannot wait for the completion of its superior context.

Who actually carries out the scheduling in a system

I came across that the process ready for execution in the ready queue are given the control of the CPU by the scheduler. The scheduler selects a process based on its scheduling algorithm and then gives the selected process the control of the CPU and later preempts if it is following a preemptive style. I would like to know that if the CPU's processing unit is being used by the processor then who exactly preempts and schedules the processes if the processing unit is not available.
now , i want to share you my thought about the OS,
and I'm sorry my English is not very fluent
What do you think about the OS? Do you think it's 'active'?
no, in my opinion , OS is just a pile of dead code in memory
and this dead code is constituted by interrupt handle function(We just called this dead code 'kernel source code')
ok, now, CPU is execute process A, and suddenly a 'interrupt' is occur, this 'interrupt' may occured because time clock or because a read system call, anyhow, a interrupt is occur. then CPU will jump the constitute interrupt handl function(CPU jump because CPU's constitute is designed). As said previously, this interrupt handle function is the part of OS kernel source code.
and CPU will execute this code. And what this code will do? this code will scheduleļ¼Œand CPU will execute this code.
Everything happens in the context of a process (Linux calls these lightweight processes but its the same).
Process scheduling generally occurs either as part of a system service call or as part of an interrupt.
In the case of a system service call, the process may determine it cannot execute so it invokes the scheduler to change the context to a new process.
The OS will schedule timer interrupts where it can do scheduling. Scheduling can also occur in other types of interrupts. Interrupts are handled by the current process.

Semaphore when using a pre-emptive kernel

I know what a binary semaphore is: it is a flag when is set to 1 by an ISR of an interrupt.
But what is a semaphore when we are using a pre-emptive kernel, say FreeRTOS? Is it the same as binary semaphore?
it is a flag when is set to 1 by an ISR of an interrupt.
That is neither a complete nor accurate description of a semaphore. What you have described is merely a flag. A semaphore is a synchronisation object; there are three forms provided by a typical RTOS:
Binary Semaphore
Counting Sempahore
Mutual Exclusion Semaphore (Mutex)
In the case of a binary semaphore, there are two operations give and take. A task taking a semaphore will block (i.e. suspend execution and allow other lower or equal priority threads to run threads to run) until some other thread or interrupt handler gives the semaphore. Binary semaphores are used to signal between threads and from ISRs to threads. They are often used to implement deferred interrupt handlers, so that an ISR can ve bery short, and the handler benefit from RTOS mechanisms that are not allowed in an ISR (anything that blocks or suspends execution).
Multiple threads may block on a single semaphore, but only one of those tasks will respond take the semaphore. Some RTOS have a flush operation (VxWorks for example) that puts all threads waiting on a semaphore in the ready state simultaneously - in which case they will run according to the priority scheduling scheme.
A Counting Semaphore is similar to a Binary Semaphore, except that it can be given multiple times, and tasks may take the semaphore without blocking until the count is zero.
A Mutex is used for resource locking. It is possible to use a binary semaphore for this, but a mutex provides features that make this safer. The operations on a mutex are lock and unlock. When a thread locks a mutex, and another task attempts to lock the same mutex, the second (and any subsequent) task blocks until the first task unlocks it. This can be used to prevent more than one thread accessing a resource (memory or I/O) simultaneously. A thread may lock a mutex multiple times; a count is maintained, so that it must be unlocked an equal number of times before the lock is released. This allows a thread to nest locks.
A special feature of a mutex is that if a thread with the lock is a lower priority that a task requesting the lock, then the lower priority task is boosted to the priority of the higher in order to prevent a priority inversion where a middle priority task may preempt the low priority task with the lock increasing the length of time the higher priority task must wait this rendering the scheduling non-deterministic.
The above descriptions are typical; specific RTOS implementations may differ. For example FreeRTOS distinguishes between a mutex and a recursive mutex, the latter supporting the nestability feature; while the first is marginally more efficient where nesting is not needed.
Semaphores are not just flags, or counts. They support send and wait operations. A user-space thread can wait on a semaphore without unnecessary and unwanted polling and be made ready/running 'immediately' when another thread, or an appropriately-designed driver/ISR, sends a unit.
By 'appropriately-designed driver/ISR', I mean one that can perform a send() operation and then exit via the OS scheduler whenever it needs to set a waiting thread ready/running.
Such a mechanism is vitally important on preemptive kernels because it allows them to achieve very good I/O performance without wasting time, CPU cycles and memory-bandwidth on polling. Non-preemptive systems are hopelessly slow, latency-ridden and wasteful at I/O and this is why they are essentially no longer used and why we put up with all the synchro/locking/queueing etc issues.

Why a mutex cannot be released from an ISR

Vxworks states that mutual exculsion semaphores : Cannot be given inside ISR, while the condition is vaild for binary and counting semaphore.
I am not able to understand the reason out the same.
Thanks,
Zaks.
Remember that a Mutex must first be acquired/taken then released/given.
In addition, the task that acquires the mutex owns it. This prevents another task from releasing a mutex it doesn't own.
With that being the case, it becomes clear that since an ISR cannot acquire a mutex (or any semaphore for that matter - it's a blocking operation), then it follows that it can't give the mutex.
It is quite possible for an ISR to do give a Binary or Counting semaphore to signal a task that something happens. But mutexes are always a take/give pair.
To clarify a point. In VxWorks, the ISR context is not the same as the context of a task!
The following scenario is invalid:
Task A ISR
semTake(mutex)
....
semGive(mutex)
Task A owns the mutex. When the ISR runs, it executes in a totaly different context. Most current processors have a separate ISR stack. Since Task A owns the mutex, how could the ISR give it up? In fact, what guarantee do you have that the ISR will fire while A has the mutex.
Even assuming you "could" give a mutex in an ISR, how would you handle the following scenario:
Task A Task B ISR
semTake(mutex)
...
<context switch happens>
<B runs>
semGive(mutex)
Task A gets switched out due to a call unrelated to the mutex, and Task B runs. The ISR now executes while B was running. Would it still be valid for the ISR to be given?
Regardless of all this, the simple fact is that a mutex is always used in a pair of Get/Set. I fail to see a use case where you would have an isolated semGive.
Is there a specific situation you have in mind that would require a semGive from an ISR context?
Mutexes should not be used from an interrupt because:
They include a priority inheritance mechanism which only makes sense if the mutex is given and taken from a task, not an interrupt.
An interrupt cannot block to wait for a resource that is guarded by a mutex to become available
https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html