/* * sched_attr.c * * Demonstrate use of POSIX 1003.1c-1995 thread priority * scheduling attributes, by creating an attributes object with * realtime scheduling policy and priority. * * Special notes: Although Solaris 2.5 defines * _POSIX_THREAD_PRIORITY_SCHEDULING, it does not support the * SCHED_RR policy for threads. */ #include <unistd.h> #include <pthread.h> #include <sched.h> #include "errors.h" /* * Thread start routine. If priority scheduling is supported, * report the thread's scheduling attributes. */ void *thread_routine (void *arg) { int my_policy; struct sched_param my_param; int status; /* * If the priority scheduling option is not defined, then we * can do nothing with the output of pthread_getschedparam, * so just report that the thread ran, and exit. */ #if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined (sun) status = pthread_getschedparam ( pthread_self (), &my_policy, &my_param); if (status != 0) err_abort (status, "Get sched"); printf ("thread_routine running at %s/%d\n", (my_policy == SCHED_FIFO ? "FIFO" : (my_policy == SCHED_RR ? "RR" : (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))), my_param.sched_priority); #else printf ("thread_routine running\n"); #endif return NULL; } int main (int argc, char *argv[]) { pthread_t thread_id; pthread_attr_t thread_attr; int thread_policy; struct sched_param thread_param; int status, rr_min_priority, rr_max_priority; status = pthread_attr_init (&thread_attr); if (status != 0) err_abort (status, "Init attr"); /* * If the priority scheduling option is defined, set various scheduling * parameters. Note that it is particularly important that you remember * to set the inheritsched attribute to PTHREAD_EXPLICIT_SCHED, or the * policy and priority that you've set will be ignored! The default * behavior is to inherit scheduling information from the creating * thread. */ #if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined (sun) status = pthread_attr_getschedpolicy ( &thread_attr, &thread_policy); if (status != 0) err_abort (status, "Get policy"); status = pthread_attr_getschedparam ( &thread_attr, &thread_param); if (status != 0) err_abort (status, "Get sched param"); printf ( "Default policy is %s, priority is %d\n", (thread_policy == SCHED_FIFO ? "FIFO" : (thread_policy == SCHED_RR ? "RR" : (thread_policy == SCHED_OTHER ? "OTHER" : "unknown"))), thread_param.sched_priority); status = pthread_attr_setschedpolicy ( &thread_attr, SCHED_RR); if (status != 0) printf ("Unable to set SCHED_RR policy.\n"); else { /* * Just for the sake of the exercise, we'll use the * middle of the priority range allowed for * SCHED_RR. This should ensure that the thread will be * run, without blocking everything else. Because any * assumptions about how a thread's priority interacts * with other threads (even in other processes) are * nonportable, especially on an implementation that * defaults to System contention scope, you may have to * adjust this code before it will work on some systems. */ rr_min_priority = sched_get_priority_min (SCHED_RR); if (rr_min_priority == -1) errno_abort ("Get SCHED_RR min priority"); rr_max_priority = sched_get_priority_max (SCHED_RR); if (rr_max_priority == -1) errno_abort ("Get SCHED_RR max priority"); thread_param.sched_priority = (rr_min_priority + rr_max_priority)/2; printf ( "SCHED_RR priority range is %d to %d: using %d\n", rr_min_priority, rr_max_priority, thread_param.sched_priority); status = pthread_attr_setschedparam ( &thread_attr, &thread_param); if (status != 0) err_abort (status, "Set params"); printf ( "Creating thread at RR/%d\n", thread_param.sched_priority); status = pthread_attr_setinheritsched ( &thread_attr, PTHREAD_EXPLICIT_SCHED); if (status != 0) err_abort (status, "Set inherit"); } #else printf ("Priority scheduling not supported\n"); #endif status = pthread_create ( &thread_id, &thread_attr, thread_routine, NULL); if (status != 0) err_abort (status, "Create thread"); status = pthread_join (thread_id, NULL); if (status != 0) err_abort (status, "Join thread"); printf ("Main exiting\n"); return 0; }
/* * sched_thread.c * * Demonstrate dynamic scheduling policy use. * * Special note: This demonstration will fail on Solaris 2.5 * because it does not implement SCHED_RR. */ #include <unistd.h> #include <pthread.h> #include <sched.h> #include "errors.h" #define THREADS 5 /* * Structure describing each thread. */ typedef struct thread_tag { int index; pthread_t id; } thread_t; thread_t threads[THREADS]; int rr_min_priority; /* * Thread start routine that will set its own priority */ void *thread_routine (void *arg) { thread_t *self = (thread_t*)arg; int my_policy; struct sched_param my_param; int status; my_param.sched_priority = rr_min_priority + self->index; DPRINTF (( "Thread %d will set SCHED_FIFO, priority %d\n", self->index, my_param.sched_priority)); status = pthread_setschedparam ( self->id, SCHED_RR, &my_param); if (status != 0) err_abort (status, "Set sched"); status = pthread_getschedparam ( self->id, &my_policy, &my_param); if (status != 0) err_abort (status, "Get sched"); printf ("thread_routine %d running at %s/%d\n", self->index, (my_policy == SCHED_FIFO ? "FIFO" : (my_policy == SCHED_RR ? "RR" : (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))), my_param.sched_priority); return NULL; } int main (int argc, char *argv[]) { int count, status; rr_min_priority = sched_get_priority_min (SCHED_RR); if (rr_min_priority == -1) { #ifdef sun if (errno == ENOSYS) { fprintf (stderr, "SCHED_RR is not supported.\n"); exit (0); } #endif errno_abort ("Get SCHED_RR min priority"); } for (count = 0; count < THREADS; count++) { threads[count].index = count; status = pthread_create ( &threads[count].id, NULL, thread_routine, (void*)&threads[count]); if (status != 0) err_abort (status, "Create thread"); } for (count = 0; count < THREADS; count++) { status = pthread_join (threads[count].id, NULL); if (status != 0) err_abort (status, "Join thread"); } printf ("Main exiting\n"); return 0; }