Structure that describes scheduling parameters
#include <sched.h> struct sched_param { int32_t sched_priority; int32_t sched_curpriority; union { int32_t reserved[8]; struct { int32_t __ss_low_priority; int32_t __ss_max_repl; struct timespec __ss_repl_period; struct timespec __ss_init_budget; } __ss; } __ss_un; } #define sched_ss_low_priority __ss_un.__ss.__ss_low_priority #define sched_ss_max_repl __ss_un.__ss.__ss_max_repl #define sched_ss_repl_period __ss_un.__ss.__ss_repl_period #define sched_ss_init_budget __ss_un.__ss.__ss_init_budget
You'll use the sched_param structure when you get or set the scheduling parameters for a thread or process.
You can use these functions to get the scheduling parameters:
You can use these functions to set the scheduling parameters:
The members of sched_param include:
When you set the scheduling parameters, set this member to the priority that you want to use. The priority must be between the minimum and maximum values returned by sched_get_priority_min() and sched_get_priority_max() for the scheduling policy.
As an extension to POSIX in QNX Neutrino 6.6 or later, you can wrap the new priority in one these macros to specify how to handle out-of-range priority requests:
If procnto was started with a -P option ending with s or S, out-of-range priority requests by default saturate at the maximum allowed value.
When you set the scheduling parameters, this member is ignored.
The other members are used with sporadic scheduling. The following #define directives create the POSIX names that correspond to those members and should be used instead of accessing members directly.
For more information, see Scheduling policies in the QNX Neutrino Microkernel chapter of the System Architecture guide.
This code shows a duty-cycle usage of the sporadic server thread:
#include <stdio.h> #include <errno.h> #include <sched.h> #include <pthread.h> #include <inttypes.h> #include <sys/syspage.h> #include <sys/neutrino.h> /* 50 % duty cycle of 5 secs on 5 secs off */ struct timespec g_init_budget = { 5, 0 }; struct timespec g_repl_period = { 10, 0 }; #define MY_HIGH_PRIORITY 5 #define MY_LOW_PRIORITY 4 #define MY_REPL_PERIOD g_repl_period #define MY_INIT_BUDGET g_init_budget #define MY_MAX_REPL 10 #define DUTY_CYCLE_LOOPS 10 /* Run a compute-bound thread (minimal blocking) to show the duty cycle. */ void *st_duty_check(void *arg) { struct sched_param params; uint64_t stime, etime, cps; double secs; int ret, prio; int prevprio, iterations; stime = ClockCycles(); cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec; iterations = 0; printf("\n"); prevprio = -1; while(iterations < DUTY_CYCLE_LOOPS) { etime = ClockCycles(); ret = pthread_getschedparam(pthread_self(), &prio, ¶ms); if(ret != 0) { printf("pthread_getschedparam() failed %d \n", errno); break; } else if (prevprio != -1 && prevprio != params.sched_priority) { stime = etime - stime; secs = (double)stime / (double)cps; printf("pri %d (cur %d) %lld cycles %g secs\n", params.sched_priority, params.sched_curpriority, stime, secs); stime = etime; iterations++; } prevprio = params.sched_priority; } return NULL; } int main(int argc, char **argv) { struct sched_param params; pthread_attr_t attr; pthread_t thr; int ret; /* Set the attribute structure with the sporadic values */ printf("# Set sporadic attributes ..."); pthread_attr_init(&attr); ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if(ret != 0) { printf("pthread_attr_setinheritsched() failed %d \n", errno); return 1; } ret = pthread_attr_setschedpolicy(&attr, SCHED_SPORADIC); if(ret != 0) { printf("pthread_attr_setschedpolicy() failed %d %d\n", ret, errno); return 1; } params.sched_priority = MY_HIGH_PRIORITY; params.sched_ss_low_priority = MY_LOW_PRIORITY; memcpy(¶ms.sched_ss_init_budget, &MY_INIT_BUDGET, sizeof(MY_INIT_BUDGET)); memcpy(¶ms.sched_ss_repl_period, &MY_REPL_PERIOD, sizeof(MY_REPL_PERIOD)); params.sched_ss_max_repl = MY_MAX_REPL; ret = pthread_attr_setschedparam(&attr, ¶ms); if(ret != 0) { printf("pthread_attr_setschedparam() failed %d \n", errno); return 1; } printf("OK\n"); /* Create a sporadic thread to check the duty cycle */ printf("# Creating thread duty cycle thread (%d changes) ... ", DUTY_CYCLE_LOOPS); ret = pthread_create(&thr, &attr, st_duty_check, NULL); if(ret != 0) { printf("pthread_create() failed %d \n", errno); return 1; } pthread_join(thr, NULL); printf("OK\n"); return 0; }
See also sched_getparam().