Scheduling in QNX : In a real-time operating system like QNX Neutrino, scheduling is the brain behind who runs the CPU and when. Think of it as a smart traffic controller — it makes sure every thread (a lightweight process) gets a fair chance to run, and that critical tasks run exactly when they need to.
Scheduling in QNX
Why Is Scheduling Important?
In real-time and embedded systems, timing is everything. Imagine an airbag system or a pacemaker — delays are not an option. QNX uses scheduling policies to ensure that high-priority threads get the CPU immediately, while lower-priority or background tasks wait their turn.
In QNX (a real-time OS), scheduling means deciding which thread (a small unit of a program) gets to run on the CPU and for how long.
Each thread has a priority, and higher-priority threads run first. If two or more threads have the same priority, then the scheduling policy decides how the OS chooses between them.
Types of Scheduling Policies in QNX
1. FIFO (First In, First Out) — SCHED_FIFO
- Threads are run in the order they become ready.
- Once a thread is running, it keeps running until it blocks or finishes.
- No time limit or time slice.
🧠 Think of it like: “First come, first served”
2. Round Robin — SCHED_RR
- Like FIFO, but each thread gets a small time slice (e.g., 10ms).
- After its time is over, it goes to the end of the line, and the next thread runs.
🧠 Think of it like: “Everyone gets a turn”
3. Sporadic — SCHED_SPORADIC
- Used for time-sensitive tasks that should not use too much CPU.
- Gives the thread high priority for a short time, then lowers it to let others run.
🧠 Think of it like: “You can run fast, but not for too long!”
4. Other — SCHED_OTHER
- Behaves like round-robin.
- Not recommended because its behavior may change in the future.
Key Points
- Each thread in QNX can have its own policy.
- These policies only matter if two threads have the same priority.
- If a higher-priority thread is ready, it runs immediately (preempts others).
Example: Set Scheduling in Code
Here’s a simple C code example showing how to:
- Get current scheduling info
- Change it to FIFO
- Increase the priority
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main() {
struct sched_param param;
int policy, retcode;
// Get current scheduling policy and priority
retcode = pthread_getschedparam(pthread_self(), &policy, ¶m);
if (retcode != 0) {
printf("Error: %s\n", strerror(retcode));
return EXIT_FAILURE;
}
printf("Current Priority: %d\n", param.sched_priority);
// Increase priority and change to FIFO
param.sched_priority += 1;
policy = SCHED_FIFO;
retcode = pthread_setschedparam(pthread_self(), policy, ¶m);
if (retcode != 0) {
printf("Error: %s\n", strerror(retcode));
return EXIT_FAILURE;
}
printf("Changed to FIFO with Priority: %d\n", param.sched_priority);
return 0;
}
Functions You Can Use
Function Name | What It Does |
---|---|
pthread_getschedparam() | Get thread’s current policy & priority |
pthread_setschedparam() | Set thread’s policy & priority |
pthread_setschedprio() | Just change the priority |
pthread_self() | Get ID of the current thread |
What is Round-Robin Scheduling?
Round-Robin (SCHED_RR) is a scheduling method used when multiple threads have the same priority.
It makes sure that every thread gets a fair share of CPU time, instead of one thread running forever.
How It Works
When a thread is selected to run, it continues until one of the following happens:
- ✅ It finishes or gives up the CPU by itself (voluntarily).
- ⛔ A higher-priority thread becomes ready (preemption).
- ⌛ It uses up its time slice (its allowed time to run).
What Is a Time Slice?
A time slice is the small chunk of time that each thread gets to run before the next thread is given a turn.
In QNX, the time slice is calculated as:
timeslice = 4 × ticksize
What is ticksize?
- It’s the basic unit of time the system uses.
- If your CPU speed > 40 MHz, then
ticksize = 1 ms
, sotimeslice = 4 ms
- If CPU speed ≤ 40 MHz, then
ticksize = 10 ms
, sotimeslice = 40 ms
💡 Most modern CPUs use 4 ms time slices.
Example Scenario
Let’s say there are 3 threads (A, B, and C) of equal priority.
- Thread A runs first and uses up its time slice (4 ms).
- Then it is moved to the end of the queue.
- Now, Thread B runs, then C, and so on.
It works like a loop, giving each thread a fair chance.
Comparison with FIFO
Feature | FIFO (SCHED_FIFO ) | Round-Robin (SCHED_RR ) |
---|---|---|
Time Slice? | ❌ No | ✅ Yes (4ms by default) |
Fairness | ⚠️ One thread can hog the CPU | ✅ Threads take turns |
Preemption allowed? | ✅ By higher-priority threads | ✅ By higher-priority threads |
Same-priority threads | Run in order, until blocked or done | Rotate using time slices |
Key Points
- Round-Robin is fair for threads with the same priority.
- If a thread finishes early, the next one runs immediately.
- It avoids CPU starvation by not letting one thread run too long.
Code: Round-Robin Thread Scheduling in C
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
void* thread_func(void* arg) {
char* name = (char*)arg;
for (int i = 0; i < 5; ++i) {
printf("Thread %s is running (iteration %d)\n", name, i + 1);
usleep(500000); // Sleep for 0.5 seconds to simulate work
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
struct sched_param param;
pthread_attr_t attr;
// Initialize thread attributes
pthread_attr_init(&attr);
// Set the scheduling policy to Round-Robin
pthread_attr_setschedpolicy(&attr, SCHED_RR);
// Set the thread priority (use a valid priority for your system)
param.sched_priority = 10;
pthread_attr_setschedparam(&attr, ¶m);
// Explicitly set inherit scheduler to EXPLICIT
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
// Create two threads using round-robin scheduling
pthread_create(&thread1, &attr, thread_func, "A");
pthread_create(&thread2, &attr, thread_func, "B");
// Wait for threads to finish
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Main thread finished.\n");
return 0;
}
Notes:
- We set the scheduling policy to
SCHED_RR
usingpthread_attr_setschedpolicy()
. - We also specify a priority using
sched_param
. PTHREAD_EXPLICIT_SCHED
is needed to override default inheritance behavior.- Threads A and B will take turns, showing fair execution.
Permissions
To run this on QNX or Linux:
- You may need root privileges (or capabilities) to set real-time scheduling.
sudo ./your_program_name
You can also Visit other tutorials of Embedded Prep
- What is eMMC (Embedded MultiMediaCard) memory ?
- Top 30+ I2C Interview Questions
- Bit Manipulation Interview Questions
- Structure and Union in c
- Little Endian vs. Big Endian: A Complete Guide
- Merge sort algorithm
Special thanks to @mr-raj for contributing to this article on Embedded Prep
Leave a Reply