1

There is much of material available regarding priority preemptive scheduling on Google and Stackoverflow, but I am still having confusion regarding scheduling of infinite loop tasks in a priority preemptive scheduling kernel. Let's consider the following case:

An RTOS starts two tasks T1 and T2 with priority 50 and 100 respectively. Both tasks look like:

void T1()
{
    while(1)
    {
        perform_some_task1();
        usleep(100);
    }
}

and

void T2()
{
    while(1)
    {
        perform_some_task2();
        usleep(100);
    }
}

As far as I understood, the kernel will schedule T2 because of its higher priority and suspend T1 because of its lower priority. Now because T2 is an infinite loop, it will never relinquish CPU to T1 until some other high priority task preempts T2.

BUT, it seems that my understanding is not correct because I have tested the above case in an RTOS and I get output on console printed by both tasks.

Can somebody comment on my understanding on the matter and the actual behavior of RTOS in above case?

Claudio
  • 10,614
  • 4
  • 31
  • 71
Arshan
  • 736
  • 6
  • 19

1 Answers1

4

In that case, both tasks are being suspended once perform_some_taskN(); have been executed (releasing the resources to be used by another threads). According to the documentation:

The usleep() function will cause the calling thread to be suspended from execution until either the number of real-time microseconds specified by the argument useconds has elapsed or a signal is delivered to the calling thread and its action is to invoke a signal-catching function or to terminate the process. The suspension time may be longer than requested due to the scheduling of other activity by the system.

BTW, usleep() is deprecated (use nanosleep() instead) :

POSIX.1-2001 declares this function obsolete; use nanosleep(2) instead. POSIX.1-2008 removes the specification of usleep().

Jose
  • 3,306
  • 1
  • 17
  • 22
  • Thanks @Jose, does it mean if I remove usleep() from both tasks, T2 will keep running and will not give up CPU for T1 to be scheduled and executed? – Arshan Jul 03 '18 at 13:08
  • 1
    Yes, it will wait till the highest priority task has been completed (forgive watchdog or any other external factor). – Jose Jul 03 '18 at 13:22
  • @Arshan - that depends on what `perform_some_task2()` does. It may also include a scheduling/blocking call. Functions that _block_ (e.g. synchronisation, IPC, delay, timer-wait, and yield functions), cause the scheduler to be invoked, and the highest priority non-blocked (i.e. _ready_) function runs. – Clifford Jul 04 '18 at 08:52
  • 1
    POSIX `usleep()` is deprecated - it is possibly that this theoretical RTOS is not POSIX - looks like pseudocode. – Clifford Jul 04 '18 at 08:56
  • @Clifford I had supposed an old POSIX example. Otherwise, my answer doesn't make sense at all, because `usleep()` might call a blocking task (given that we don't know what `usleep()` does), being not suspended from execution the current highest priority task. – Jose Jul 04 '18 at 09:08
  • @JoseFelipe it is a fair assumption that usleep is blocking. The point about POSIX usleep perhaps better in a comment rather than the answer, but it is not critical IMO, remains a good answer. – Clifford Jul 04 '18 at 09:12
  • Thank you @Clifford – Jose Jul 04 '18 at 09:14
  • @Clifford! yes it was a pseudocode but the answer really helped me clear the concept. AFIK the sleep()/delay() function in most RTOSes does the same as mentioned by Jose in his answer. – Arshan Jul 04 '18 at 10:52