FreeRTOS task is taking more than the previous one, what will happen with the previous and current one? - freertos

Suppose that we have Task 1 and Task 2 started on the same core.
Task 1 is the first to be run by the Scheduler and calls the vTaskDelay(100 / portTICK_PERIOD_MS).
Scheduler then sees that Task 1 is now in blocked state and runs Task 2, but Task 2 is taking 200 ms to execute. What will happen with Task 1:
Will the Scheduler Block Task 2 after 100 ms to return back to Task 1
Will the Scheduler continue executing Task 2 and after that back to Task 1, which means that the delay will not be 100 ms for Task 1
I have tried somehow to block Task 2 for more that the Task 1's delay, but I can't.
EDIT:
Test - Task 1 has highest priority than Task 2:
Task 1 will be executed first,because it has higher priority than Task 2.
During the execution Task 1 will be delayed for 100 ms and put to blocked state.
The Scheduler behind checks at interval all tasks and will see that Task 1 is blocked and Task 2 is ready and will execute it.
While the Task 2 is executed 100 ms have passed and the Scheduler behind will see that Task 1 is at ready state and will execute it, because it has higher priority than Task 1. Due to that Task 2 will be blocked.
After the execution of Task 1 the Scheduler will see that Task 2 is in ready state and will execute it.
My throughts:
For me it looks like there is a notification behind all of that. If a task has been delayed it will be blocked, but a notification after the delay will set the Task again in ready state.
Meanwhile there is a periodic check from the Scheduler and if he finds a Task that has higher priority than the current executing one it will block it and execute the one with higher priority.
Then:
a) Will the Scheduler Block Task 2 after 100 ms to return back to Task 1 - Only if Task 1 has higher priority than Task 2
b) Will the Scheduler continue executing Task 2 and after that back to Task 1, which means that the delay will not be 100 ms for Task 1 - Only if Task 1 and Task 2 have same priority.

It depends if the kernel is configured as preemptive or not.
In preemptive configuration (which is the default one), delays are evaluated on each RTOS tick, and Task 1's state changes from blocked to ready. If it's the highest priority task in the system, the scheduler switches to it.
In cooperative configuration, Task 2 continues to run until it blocks on a semaphore, queue etc. or calls taskYIELD() even after Task 1 becomes ready again. I'm not sure if periodic tick interrupt still occurs and updates task states which are blocked on delays.

Related

Rails enqueue jobs and execute after x time from previous

I have a rails api app where receives a bunch of requests and then, for each, it executes a job, but I want to prevent it job being called immediately, I need it delay 2 seconds. So for that I have MyAwesomeJob.perform_in(2.seconds, stuff). So looking to sidekiq it goes right after 2 seconds. But next request goes right away.
What I need is: having 10 requests in 1 second it should enqueue 10 jobs and execute it one after other. (first gonna be in 2 seconds, next should wait last finish and go, so 4 seconds, 6seconds etc....)
Thanks!

multiple definitions for serial queue online, so got confused

i have came across two kind of definitions for serial queue after reading online.
1st version: serial queue performs one task at a time.
2nd version: serial queue execute tasks serially, so task1 have to finish before task2 starts.
can you tell me which one is right exactly ?
As Ratul Sharker said, both versions are saying the same thing.
1st version: serial queue performs one task at a time.
You only can have one task running, so your task have to finish before another is started.
Task 1 starts
Task 1 ends
Task 2 starts
Task 2 ends
2nd version: serial queue execute tasks serially, so task1 have to finish before task2 starts
Obviously, the result is the same as the 1st version.
But! That 2nd version might be speaking of callbacks or another sort of paradigms with multithreading, where you could run more than one task, but Task 2 will wait for Task 1 to end.
In any case, two tasks are serial if one starts after the other ends, simple as that.
From the appledoc
Operations within a queue are organized according to their readiness, priority level, and interoperation dependencies, and are executed accordingly. If all of the queued operations have the same queuePriority and are ready to execute when they are put in the queue—that is, their isReady property returns true—they’re executed in the order in which they were submitted to the queue. Otherwise, the operation queue always executes the one with the highest priority relative to the other ready operations.
However, you should never rely on queue semantics to ensure a specific execution order of operations, because changes in the readiness of an operation can change the resulting execution order. Interoperation dependencies provide an absolute execution order for operations, even if those operations are located in different operation queues. An operation object is not considered ready to execute until all of its dependent operations have finished executing.
So the queued operations are intended to be executed serially, but it never garunteed. To ensure execution order dependencies must be specified to get the full proof exact behaviour.

freertos subpriority of xSemaphoreTake() within same priority tasks

I have three tasks with same priority.
Task A
mutextake()
//critical code
mutexgive()
Task B
mutextake()
//critical code
mutexgive()
Task C
mutextake()
//critical code
mutexgive()
Each of them run critical code guarded by a mutex. However I would like to set a "subpriority" to who would take the mutex in the event that two of the tasks are blocking waiting for the mutex. I dont want to set the tasks with different priorities as this will cause complications within the design of other tasks. Is this a feature with freertos to set a "subpriority" for a task to grab a mutex before another of the same priority?
In a word "no". FreeRTOS inter-task communication objects (https://www.freertos.org/Inter-Task-Communication.html) have lists of tasks waiting to send and lists of tasks waiting to receive (taking a mutex being a receive). The task in the list that succeeds when the operation can complete is the task with the highest priority - or if the tasks have equal priority - the task that has been waiting the longest.

Quartz scheduling queues up missed scheduled jobs

I have a quartz job schedule like so:
_scheduler.ScheduleJob(job,
TriggerBuilder.Create().ForJob(job)
.WithSimpleSchedule(x =>
x.WithIntervalInSeconds(requeryTime.ToInt32())
.RepeatForever()
.WithMisfireHandlingInstructionNowWithRemainingCount()
)
.StartNow()
.Build())
To test I have the schedule run every 10 seconds. If I pause the service and then resume, I can still see all the jobs being called one after another. I want Quartz to ignore (do not queue) the jobs and just resume the schedule.
e.g. If the job runs every 10 secs and I pause the service for 1 minute, I get 6 jobs run in quick succession.
How do I go about ensuring Quartz ignores those jobs?
Short answer is to change the misfireThreshold in the configuration:
<add key="quartz.jobStore.misfireThreshold" value="60000" />
The default is 60000 milliseconds (60 seconds).
org.quartz.jobStore.misfireThreshold
The the number of milliseconds the scheduler will 'tolerate' a trigger
to pass its next-fire-time by, before being considered "misfired". The
default value (if you don't make an entry of this property in your
configuration) is 60000 (60 seconds).
Since your trigger runs every 10 seconds you can reduce the threshold to 9 seconds and it should work as you expect.
If you want to learn more about the strategies involved you can read this article and this one as well.
A similar question has been asked recenlty and Circular Reference gave a really good answer.

iOS GCD custom concurrent queue execution sequence

I have question regarding this issue ,
According to Apple's documents
Concurrent
Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.
In iOS 5 and later, you can create concurrent dispatch queues yourself by specifying DISPATCH_QUEUE_CONCURRENT as the queue type. In addition, there are four predefined global concurrent queues for your application to use. For more information on how to get the global concurrent queues, see Getting the Global Concurrent Dispatch Queues.
And i do a test, using the sample code ,
dispatch_queue_t concurrentQueue;
concurrentQueue = dispatch_queue_create("com.gcd.concurrentQueue",
DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
NSLog(#"First job ");
});
dispatch_async(concurrentQueue, ^{
NSLog(#"Second job");
});
dispatch_async(concurrentQueue, ^{
NSLog(#"Third job ");
});
But the results seems not as the order in which they are added, here is the results,
2015-06-03 18:36:38.114 GooglyPuff[58461:1110680] First job
2015-06-03 18:36:38.114 GooglyPuff[58461:1110682] Third job
2015-06-03 18:36:38.114 GooglyPuff[58461:1110679] Second job
So my question is , shouldn't it be
First, Second , Third ?
Any advice is welcome , and thanks for your help.
"Concurrent" means they run at the same time and no assumptions should be made about where in their progress any of them will be at any given moment and which will finish first. That is the whole meaning and implication of concurrency: between one line of code and the next in one concurrent operation - even during one line of code - anything else from any other concurrent operation might be happening.
So, in answer to your particular question, these tasks may have started in a known order, but that happened very quickly, and after that point their progress is interleaved unpredictably. And your NSLog calls are part of that progress; they do not, and cannot, tell you when the tasks started!
The documentation is correct - they will indeed start in the order you added them to the queue. Once in the queue, they will be started one after the other, but on concurrent threads. The order they will finish is dependent on how long the task will take to execute. Here's a thought experiment, imagine your code was like this instead:
dispatch_async(concurrentQueue, ^{
JobThatTakes_3_SecToExecute(); // Job 1 (3 seconds to execute)
});
dispatch_async(concurrentQueue, ^{
JobThatTakes_2_SecToExecute(); // Job 2 (2 seconds to execute)
});
dispatch_async(concurrentQueue, ^{
JobThatTakes_1_SecToExecute(); // Job 3 (1 second to execute)
});
The overhead in and out of the queue should be very small compared to these job lengths, so you would expect them to finish up in about the time that their task takes to execute. In this case they'd finish roughly 1 second apart starting with Job 3, then 2, then 1. The total time the queue would take to complete will be about the length of Job 1, since it takes the longest to execute. This is lovely, since the total time is set primarily by the longest job, not the sum of the jobs. However, you don't have any say in what order they finish, since that's dictated by the task duration.
Change dispatch_async to dispatch_sync in this example and the queue will take about 6 seconds to complete. They'll come out in this order: Job 1, 2, then 3. This will guarantee that your results come out in the order you wanted, but it will take much longer.
So back to the significance of what the docs mean by "tasks are still started in the order in which they were added to the queue" for concurrent queues. This will be noticeable if your job is resource constrained. Say you're putting a big pile of long duration tasks in a concurrent queue on a 2 CPU machine. It is unlikely you'll be able to run a dozen CPU-pegging tasks concurrently here; some will have to wait while others run. The order that you put them into the queue will decide who gets to run next as resources free up. In your example, the tasks are of super short duration and involve console locking (as Rob mentioned), so queue / locking overhead can mess with your expectations.
Another (probably more important) reason the order of execution in concurrent queues matter is when barriers are used. You may need to run some sort of a task every N other tasks, which is where a barrier would come in handy. The fixed order of execution will assure that the barrier executes after N tasks have completed concurrently, provided you put the barrier in the queue in the right spot.

Resources