Breaking a tie in round robin scheduling - process

I am confused with a basic concept of Round Robin CPU process scheduling, where the short term scheduler adds the process to the ready queue.
If there are 3 process P0, P1 and P2 in the system and a context switch occurs for P1 at 5 seconds and at the same time P2 ARRIVES (i.e. at 5th second). In such a case which process will be inserted first in the ready queue, P1 or P2?
The overall average waiting time may not differ in both the cases but the individual waiting time of a process will differ.

It's not possible for both P1 and P2 to be added to the ready queue at the same time. There must be some order in which they are added (either P1 is added before P2, or P2 is added before P1), since when you want to add a process to the ready queue, you must synchronize accesses to the ready queue in order to avoid corrupting the queue. On a single core system, you might do this by disabling interrupts while you are modifying the queue. On a multicore system, you might do this through some combination of locks and disabling interrupts, depending on the implementation of the kernel.
As an example on a single core, let's say a timer interrupt arrives that causes you to preempt P1. You disable interrupts when the timer interrupt is received. While you are adding P1 to the queue, it is not possible for P2 to become available, whether this is due to some I/O completing for P2, or the user starting up P2, etc. Interrupts have been disabled, so your kernel won't be bothered with any events regarding P2 until it has added P1 to the queue and enabled interrupts. The same is true for P2 - if you are adding P2 to the queue and a timer interrupt arrives that should cause P1 to be preempted, the timer interrupt will just be ignored until P2 has been added to the queue.

P1 will be given fist chance of execution because of its aging. While P2 will be added at the end of queue just before the last executed process.
This means that P1 will start executing and P2 will be added at end of queue, just before last executed proces i.e. P0. Thus your ready queue will be like P1, P2, P0 where P1 is currently executing.

Related

RabbitMQ / AMQP: multiple queues, single consumer

I want to create a consumer that process messages from multiple variable number of sources, that are connected or disconnected dynamically.
What I need is that each consumer prioritize first N messages of each source. Then to run multiple consumers to improve the speed.
I have been reading docs for Work queues, Routing and Topics, and a lot of other docs without identifying how to implement this. Also I made some tests without luck.
Can someone point me how to do it or where to read about it?
--EDIT--
QueueA-----A3--A2--A1-┐
QueueB-----B3--B2--B1-┼------ Consumer
QueueC-----C3--C2--C1-┘
The desired effect is that each consumer gets first messages of each queue. For example: A1, B1, C1, A2, B2, C2, A3, B3, C3, and so on. If a new queue is created (QueueD), the consumer would start receiving messages from it in the same fashion.
Thanks in advance
What I need is that each consumer prioritize first N messages of each source. Then to run multiple consumers to improve the speed.
All message queues that I know of only provide ordering guarantees within the queue itself (Kafka provides ordering guarantee not at queue level but within the partitions within queues). However, here you are asking to serialize multiple queues. Which will not be possible in a distributed system context.
Why? because if you have more than one consumers to these queues, messages will be delivered to each connected consumers of a queue in a round robin fashion.
Assuming a prefetch_count=1 and with two connected consumers, say first set of messages delivered as follows:
A1, B1 & C1 delivered to consumer 1 (X)
A2, B2 & C2 delivered to consumer 2 (Y)
Now, in a distributed system, everything is async, and things could go wrong. For example:
If X acks A1, A3 will be delivered to X. But if Y acks A2 before X, A3 will be delivered to Y.
Who acks first is not within your control in a distributed system. Consider following scenarios:
X might had to wait for I/O or CPU bound task, while Y might got lucky that it doesn't had to wait. Then Y will advance through the messages in queue.
Or Y got killed (a partition) or n/w got slow, then X will continue consuming the queue.
I'll strongly advice you to re-think your requirements, and consider your expected guarantees in an async context (you wouldn't be considering a MoM otherwise, would you?).
PS: it is possible to implement what you are asking for with some consumer side logic (with a penalty on performance/throughput).
A single consumer has to connect to all queues
wait for messages from every queue before Ack'ing the messages.
Once a message from every queue is received, group them as a single message and publish to another queue (P).
Now many consumers could be subscribed to P to process the ordered group of messages.
I do not advise it, but hey, it is your system, who is going to stop you ;)

Sending second message after acknowledge of first one. Does RabbitMQ guarantee the order?

Assume several producers publish to the same exchange E (fanout). Each producer has its own channel. Queue Q is bound to exchange E. producer P1 publishes message M1 to E and receives acknowledge A1 from E. Only after acknowledge A1 second producer P2 publishes second message M2. Does RabbitMQ guarantie order of messages in Q: M1 is first, M2 is second? That is will subscribed to Q consumer always receive M1 and after that M2?
RabbitMQ guarantees order of messages in a queue: First In, First Out. The first message to go into the queue will be the first message to come out of the queue, and they will remain in order (assuming you are just consuming and acking them... if you start nacking / rejecting message, re-publishing them, etc, things change)
That is the only guarantee that it will make on the order of messages: FIFO Queues.
If you need to guarantee the order that messages are delivered to a queue, you have to build that process yourself.
FWIW, it's very difficult to build this guarantee. The only truly guaranteed way to ensure the order of messages is not to send the next one until after the first one has been processed.
Even if you wait for the publisher acknowledgement before sending the next one, it is possible for the next one to end up in the queue before the first one (though it is highly unlikely).
You may want to look into Message Sequence and Resequencer if you need to guarantee the client gets messages in a certain order.

priority control with semaphore

Suppose I have a semaphore to control access to a dispatch_queue_t.
I wait for the semaphore (dispatch_semaphore_wait) before scheduling a block on the dispatch queue.
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER)
dispatch_async(queue){ //do work ; dispatch_semaphore_signal(semaphore); }
Suppose I have work waiting in several separate locations. Some "work" have higher priority than the other "work".
Is there a way to control which of the "work" will be scheduled next?
Additional information: using a serial queue without a semaphore is not an option for me because the "work" consist of its own queue with several blocks. All of the work queue has to run, or none of it. No work queues can run simultaneously. I have all of this working fine, except for the priority control.
Edit: (in response to Jeremy, moved from comments)
Ok, suppose you have a device/file/whatever like a printer. A print job consists of multiple function calls/blocks (print header, then print figure, then print text,...) grouped together in a transaction. Put these blocks on a serial queue. One queue per transaction.
However you can have multiple print jobs/transactions. Blocks from different print jobs/transactions can not be mixed. So how do you ensure that a transaction queue runs all of its jobs and that a transaction queue is not started before another queue has finished? (I am not printing, just using this as an example).
Semaphores are used to regulate the use of finite resources.
https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html
Concurrency Programming Guide
The next step I am trying to figure out is how to run one transaction before another.
You are misusing the API here. You should not be using semaphores to control what gets scheduled to dispatch queues.
If you want to serialize execution of blocks on the queue, then use a serial queue rather than a concurrent queue.
If different blocks that you are enqueuing have different priority, then you should express that different priority using the QOS mechanisms added in OS X 10.10 and iOS 8.0. If you need to run on older systems, then you can use the different priority global concurrent queues for appropriate work. Beyond that, there isn't much control on older systems.
Furthermore, semaphores inherently work against priority inheritance since there is no way for the system to determine who will signal the semaphore and thus you can easily end up in a situation where a higher priority thread will be blocked for a long time waiting for a lower priority thread to signal the semaphore. This is called priority inversion.

VxWorks signals

I have a question regarding previous question asked in VxWorks forum.
My goal is when the high priority function generates a signal the low priority function will handle it immidiately(the high priority function must be preempted)
The code is:
sig_hdr () { ... }
task_low_priority() {
...
// Install signal handler for SIGUSR1
signal(SIGUSR1, sig_hdr);
...
}
task_high_priority() {
...
kill(pid, SIGUSR1); //pid is the ID of task_low_priority
...
}
After the line:
signal(SIGUSR1, sig_hdr);
i added
taskDelay(0).
I wanted to block the high priority task so the low priority task can gain the CPU in order to execute the signal handler but it does not happen unless i do taskDelay(1).
Can any one explain why it does not work with taskDelay(0)?
Indeed, taskDelay(0) will not let lower priority tasks run because of the following:
high priority task is executing
high priority task issues taskDelay(0)
Scheduler is invoked and it scans for the next task to run, it will select the highest priority task that is "ready"
The task that issued the taskDelay(0) is ready because the delay has expired (i.e. 0 ticks have elapsed)
So the high priority task is rescheduled immediately, in this case taskDelay(0) is effectively a waste of CPU cycles.
Now in the case where you issue taskDelay(1) the same steps are followed, but the difference is that the high priority task isn't in the ready state because one tick has not elapsed, so a lower priority task that is ready can have 1 tick of CPU time then it will be preempted by the high priority task.
Now there are some poorly designed systems out there that do things like:
taskLock();
...
taskDelay(0);
...
taskUnlock();
With the intention of having a low priority task hog the CPU until some point where it then allows a high priority task to take over by issuing a taskDelay(0). However if you play games like this then you should reconsider your design.
Also in your case I would consider a more robust system, rather than doing a taskDelay() to allow a low priority task to process an event, you should send a message to a low priority task and have that low priority task to process the message queue. While your high priority task blocks on a semaphore that is given by your event handler or some thing similar. In this situation you are hoping to force a ping pong between two different tasks to get a job done, but if you add a queue that will act as a buffer, so as long as your system is schedulable (i.e. there is enough time to respond to all events, queue them up and fully process them) then it will work.
Update
I assume your system is supposed to be something like this:
Event occurs (interrupt driven?).
High priority task runs to gather data.
Data is processed by low priority task.
If this is the case the pattern you want to follow is actually quite simple, and in fact could be accomplished with just 1 task:
Interrupt handler gathers data, and sends a message (msgQSend()) to task.
Task is pending on the message queue with msgQReceive.
But it might help if I knew more about your system (what are you really trying to do) and also why you are using posix calls rather than native vxworks calls.
If you are new to real time systems, you should learn about Rate monotonic analysis, there is a very brief summary on wikipedia:
http://en.wikipedia.org/wiki/Rate-monotonic_scheduling
Also note that in VxWorks a "high priority" is 0, and "low priority" is 255, the actual numbers are inversely related to their meaning :D
this is exactly the point i dont understand how the low priority task will get some CPU time when the high priority task is running?
High priority task will continue run till it gets blocked. OInce it gets blocked, lower priority task that are ready run will run.
My answer has 2 parts:
1. How to use correctly task Delay with vxWorks
2. TaskDelay is not the correct solution for your problem
First part:
TaskDelay in vxWorks can confused:
taskDelay(0) – don't perform delay at all!!!
It is a command to the scheduler to remove the current task from the CPU. If this is still the highest priority task in the system, it will return to the head of the queue with no delay at all. You will use this command if the scheduler configured to FIFO in case tasks in the same priority and your task have a CPU real time consumer function to run, the can try to release the CPU for other tasks in the same priority (nice).
BTW, it is the same as taskDelay(NO_WAIT).
TaskDelay(1) – this will delay the calling task sometime between zero (!!!) to 1 system tick. The delay in vxWorks finish at a round system tick.
TaskDelay(2) – sometime between 1 system tick to 2 system ticks.
3 …… (understood…)
TaksDelay(-1) (A.K.A taskDelay(WAIT_FOREVER)) – will delay the task forever (not recommended).
Second part:
Using taskDelay to enable low priority task might be a wrong idea. You didn't provided the all problem information but please note that delaying the high priority task will not ensure your low priority task will run (regardless the sleep time you'll write). Other tasks in highest priority from your high & low priority tasks might run for the all 'sleep time'.
There are several synchronized methods in vxWorks, like binary semaphores, changing task priority, signals, …

How does VxWorks prioritize interrupt bottom-halves?

Suppose I have two tasks, 'A' and 'B', of differing priority executing on SMP-supported VxWorks. Both 'A' and 'B' issue a command to an I/O device (such as a disk or NIC) and both block waiting for results. That is, both 'A' and 'B' are blocked at the same time. Some time later, the I/O device raises an interrupt and the ISR is invoked. The ISR then dispatches deferred work (aka "bottom-half") to a worker-task. Question: What is the priority of the worker-task?
VxWorks Device Driver Developer's Guide is a bit vague. It appears that the priority of the worker-task is set up a-priori. There are no automatic inheritance mechanisms that will increase the priority of the worker-task based upon the priorities of tasks ('A' and 'B') that are blocked waiting for results. This is similar to how threaded interrupt priorities work in PREEMPT_RT Linux. However, both QNX Neutrino and LynxOS will schedule the worker-task with the maximum priority of the blocked tasks-- Ex. priority(worker) = max_priority(A, B).
Can anyone clarify?
It depends exactly on which mechanism the "ISR dispatched deferred work" uses.
If a semaphore/messageQueue/Event is used, then the recipient task (A or B) will run at the priority specified when the task was created. In this scenario, the interrupt is essentially finished, and the task (A and/or B) are ready to run.
Whichever task is has the highest priority will get to run and perform it's work. Note that the task doesn't have access to any information from the interrupt context. If you use global structures (yuk) or pass data via a message queue, then the task could access those elements.
The network stack task (tNetTask) uses this approach, and a semaphore signals tNetTask when a packet has been received. When tNetTask has processed the packet (packet reassembly, etc...), it is then forwarded to whichever task is waiting on the corresponding socket.
It is possible to defer work from an ISR to tExcTask (via a call to excJobAdd). Note that with this approach, excJobAdd takes the pointer to a function and executes the function in the context of the tExcTask (which is at the highest priority in the system). It does not act as a self-contained task.
Note that some things like file systems, SCSI drivers, USB, etc... are much more than a simple driver with interrupts. They include a number of different components that unfortunately also increases complexity.