SCHED_SPORADIC

Sporadic scheduling does not appear to work the way I understand
it should.

Here is how I create a sporadic thread:


pthread_attr_t attr;
sched_param param;

pthread_attr_init(&attr);
memset(&param, ‘\0’, sizeof param);

param.sched_priority=sched_get_priority_max(SCHED_SPORADIC)-10;
param.sched_ss_low_priority=sched_get_priority_min(SCHED_SPORADIC)+5;
param.sched_ss_max_repl=3;
nsec2timespec(&param.sched_ss_repl_period, 401000000);
nsec2timespec(&param.sched_ss_init_budget, 20
1000000);

pthread_attr_setschedparam(&attr, &param);
pthread_attr_setschedpolicy(&attr, SCHED_SPORADIC);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

pthread_create((pthread_t *)thread, &attr, sporadic_thread, NULL);

As long as sporadic_thread blocks (at least once), the sporadic
scheduling appears to work (i.e. I can see the thread has a prio of
“53?”); however, it does not ever appear to decay to the low priority.

Should I not see it at least some time at the low priority (I never do) ?

The fact that it does not decay can be confirmed by changing the
threads code so that it does not block, at which point the system
freezes (requiring a reboot).

The scheduler should decay the priority of this thread to the lower
priority even if it never blocks, should it not (given the above
parameters) ?

Thanks for any help on this.

“Rennie Allen” <rallen@csical.com> wrote in message
news:br2cqi$d4f$1@inn.qnx.com

Sporadic scheduling does not appear to work the way I understand
it should.

Here is how I create a sporadic thread:


pthread_attr_t attr;
sched_param param;

pthread_attr_init(&attr);
memset(&param, ‘\0’, sizeof param);

param.sched_priority=sched_get_priority_max(SCHED_SPORADIC)-10;
param.sched_ss_low_priority=sched_get_priority_min(SCHED_SPORADIC)+5;
param.sched_ss_max_repl=3;
nsec2timespec(&param.sched_ss_repl_period, 401000000);
nsec2timespec(&param.sched_ss_init_budget, 20
1000000);

pthread_attr_setschedparam(&attr, &param);
pthread_attr_setschedpolicy(&attr, SCHED_SPORADIC);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

pthread_create((pthread_t *)thread, &attr, sporadic_thread, NULL);

As long as sporadic_thread blocks (at least once), the sporadic
scheduling appears to work (i.e. I can see the thread has a prio of
“53?”); however, it does not ever appear to decay to the low priority.

Should I not see it at least some time at the low priority (I never do) ?

The fact that it does not decay can be confirmed by changing the
threads code so that it does not block, at which point the system
freezes (requiring a reboot).

The scheduler should decay the priority of this thread to the lower
priority even if it never blocks, should it not (given the above
parameters) ?

Not necessarily. It depends on what the thread is doing during each
of the intervals you have defined.

If the thread consumes more than 20ms of CPU during a 40ms interval,
its priority will be dropped – I don’t think decay carries the right
connotation here – to the lower priority.

At the beginning of the next 40ms interval, it has its budget replenished,
so it can use another 20ms of CPU at the higher priority. It can do this
up to three times. If it finishes after 120 ms or doesn’t use more than
20 ms in any interval, or more after the third interval than the remaining
unused budget, the priority won’t be lowered.

This is useful if, say, the thread is handling events at a maximum arrival
rate of 5 every 40 ms, and they take on average 4 ms to handle. In such
cases,
if I take longer than 4 ms to process one and if the total exceeds 20ms, the
thread
misses its deadline, but doesn’t affect periodic threads’ deadlines.

This also allows compute-bound activities with a longer deadline, D1, to run
in up to 20 ms
chunks for a longer period as long as the sched_priority is set to the
appropriate
RMS priority for a 20ms/40ms rate
, and min_priority is set below all RMS
scheduled
priorities.

e.g. D1 = Now + 120 ms.
Cost = 60 ms.
is broken in to Ci = 20 ms computations over Ti = 40 ms periods.

and Ci/Ti can be admitted in to the existing (SUM(Cj/Tj) <
Capacity, for all j < i) schedule, and
sched_priority is set to the priority derived for the 20ms/40ms
rate.

If it doesn’t exceed its total budget (60ms), it will complete by
its deadline.

Thanks for any help on this.

Thanks for responding Steve.

I have narrowed down what my problem is somewhat. If I write a test case with a single SCHED_SPORADIC thread, it behaves exactly as
I believe it should (and as you describe). Unfortunately the thread in question is part of a large process with 15 threads, and even
though it has identical parameters to the test case (and all the other threads run at prio 10 with round-robin scheduling), it does
not behave the same.

I really think there is some issue with SCHED_SPORADIC here, since I put some debug in and I found that it actually operates
correctly for about 50 scheduling cycles and then the system freezes to the point that a prio 63 shell cannot do anything, and
NUMLOCK won’t toggle on the keyboard.

I obviously don’t have a simple testcase, since it seems to require the presence of the other threads to cause a problem. There is
very little interaction between the other threads and the SCHED_SPORADIC threads other than communication through an in memory queue
(a mutex is used to syncrhonize access to the queue). It could be a problem in my code, but it is obviously very difficult to
diagnose when the system freezes (it freezes regardless of the “high priority” setting, even a “high prio” lower than 10 will cause a
freeze).

Rennie