http://www.linuxforums.org/forum/linux-programming-scripting/114957-linux-thread-scheduling-question.html
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <time.h>
#include <unistd.h>
/*--------------------------------------------------------------------------*/
#define DESIRED_WORKLOAD_SECONDS 2
#define TIME_ARRAY_ELEMENTS 10
#define DESIRED_MAJOR_PRIORITY 93
#define DESIRED_MINOR_PRIORITY 91
int requested_major_priority;
int requested_minor_priority;
int observed_max_priority;
int observed_min_priority;
long long iterations_before_checking_time;
time_t major_work_array[TIME_ARRAY_ELEMENTS];
time_t minor_work_array[TIME_ARRAY_ELEMENTS];
/*--------------------------------------------------------------------------*/
void calculate_workload(void);
void check_error(char *activity,
int status
);
void do_work(time_t *time_array);
void *major_code(void *something);
void *minor_code(void *something);
/*--------------------------------------------------------------------------*/
void calculate_workload(void)
{
volatile long long counter;
long long limit;
time_t start;
/*
* We want something that will last between DESIRED_WORKLOAD_SECONDS and
* twice that.
*/
printf("calculating workload\n"
"could take up to %d seconds\n"
"trying limit =",
4*DESIRED_WORKLOAD_SECONDS
);
fflush(stdout);
for(limit=1;
;
limit<<=1
)
{
printf(" %lld",
limit
);
fflush(stdout);
start=time(NULL);
for(counter=0;
counter<limit;
counter++
)
{
/* Empty block. */
}
if(time(NULL)-start>=DESIRED_WORKLOAD_SECONDS)
{
break; /* <--------- */
}
}
iterations_before_checking_time=limit;
printf("\ndone calculating workload\n");
} /* calculate_workload() */
/*--------------------------------------------------------------------------*/
void check_error(char *activity,
int status
)
{
if(status)
{
fprintf(stderr,
"error %d %s\n",
status,
activity
);
exit(1);
}
} /* check_error() */
/*--------------------------------------------------------------------------*/
void do_work(time_t *time_array)
{
int slice_number;
volatile long long counter;
for(slice_number=0;
slice_number<TIME_ARRAY_ELEMENTS;
slice_number++
)
{
for(counter=0;
counter<iterations_before_checking_time;
counter++
)
{
/* Empty block. */
}
time_array[slice_number]=time(NULL);
}
} /* do_work() */
/*--------------------------------------------------------------------------*/
void *major_code(void *something)
{
pthread_t minor_thread_id;
pthread_attr_t thread_attributes;
struct sched_param thread_parameters;
check_error("pthread_attr_init()",
pthread_attr_init(&thread_attributes)
);
check_error("setting SCHED_RR for minor thread",
pthread_attr_setschedpolicy(&thread_attributes,
SCHED_RR
)
);
thread_parameters.sched_priority=requested_minor_priority;
check_error("setting scheduling parameters for minor thread",
pthread_attr_setschedparam(&thread_attributes,
&thread_parameters
)
);
check_error("setting explicit (not inherited) scheduling for minor thread",
pthread_attr_setinheritsched(&thread_attributes,
PTHREAD_EXPLICIT_SCHED
)
);
check_error("creating minor thread (maybe because you\'re not root?)",
pthread_create(&minor_thread_id,
&thread_attributes,
minor_code,
NULL
)
);
do_work(major_work_array);
check_error("joining minor thread",
pthread_join(minor_thread_id,
NULL
)
);
return NULL;
} /* major_code() */
/*--------------------------------------------------------------------------*/
void *minor_code(void *something)
{
do_work(minor_work_array);
return NULL;
} /* minor_code() */
/*--------------------------------------------------------------------------*/
int main(void)
{
int jndex;
pthread_t major_thread_id;
pthread_attr_t thread_attributes;
struct sched_param thread_parameters;
struct tm *the_local_time;
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined (sun)
#else
fprintf(stderr,
"priority scheduling not supported\n"
);
exit(1);
#endif
calculate_workload();
observed_min_priority=sched_get_priority_min(SCHED_RR);
observed_max_priority=sched_get_priority_max(SCHED_RR);
if((observed_min_priority>=observed_max_priority) &&
(DESIRED_MAJOR_PRIORITY!=DESIRED_MINOR_PRIORITY)
)
{
fprintf(stderr,
"observed minimum priority %d >= observed maximum priority %d\n",
observed_min_priority,
observed_max_priority
);
exit(1);
}
requested_major_priority=DESIRED_MAJOR_PRIORITY;
requested_minor_priority=DESIRED_MINOR_PRIORITY;
if(requested_major_priority==requested_minor_priority)
{
if(requested_major_priority>observed_max_priority)
{
requested_major_priority=observed_max_priority;
requested_minor_priority=observed_max_priority;
}
if(requested_major_priority<observed_min_priority)
{
requested_major_priority=observed_min_priority;
requested_minor_priority=observed_min_priority;
}
}
else
if(requested_major_priority<requested_minor_priority)
{
if(requested_minor_priority>observed_max_priority)
{
requested_minor_priority=observed_max_priority;
if(requested_major_priority>=requested_minor_priority)
{
requested_major_priority=requested_minor_priority-1;
}
}
if(requested_major_priority<observed_min_priority)
{
requested_major_priority=observed_min_priority;
if(requested_minor_priority<=requested_major_priority)
{
requested_minor_priority=requested_major_priority+1;
}
}
}
else /* requested_major_priority>requested_minor_priority */
{
if(requested_major_priority>observed_max_priority)
{
requested_major_priority=observed_max_priority;
if(requested_minor_priority>=requested_major_priority)
{
requested_minor_priority=requested_major_priority-1;
}
}
if(requested_minor_priority<observed_min_priority)
{
requested_minor_priority=observed_min_priority;
if(requested_major_priority<=requested_minor_priority)
{
requested_major_priority=requested_minor_priority+1;
}
}
}
if((requested_major_priority!=DESIRED_MAJOR_PRIORITY)
||
(requested_minor_priority!=DESIRED_MINOR_PRIORITY)
)
{
printf("The desired major and minor priorities were %d and %d.\n"
"We adjusted them to %d and %d,\n"
"because the minimum priority is %d\n"
"and the maximum priority is %d\n",
DESIRED_MAJOR_PRIORITY,
DESIRED_MINOR_PRIORITY,
requested_major_priority,
requested_minor_priority,
observed_min_priority,
observed_max_priority
);
}
check_error("pthread_attr_init()",
pthread_attr_init(&thread_attributes)
);
check_error("setting SCHED_RR for major thread",
pthread_attr_setschedpolicy(&thread_attributes,
SCHED_RR
)
);
thread_parameters.sched_priority=requested_major_priority;
check_error("setting scheduling parameters for major thread",
pthread_attr_setschedparam(&thread_attributes,
&thread_parameters
)
);
check_error("setting explicit (not inherited) scheduling for major thread",
pthread_attr_setinheritsched(&thread_attributes,
PTHREAD_EXPLICIT_SCHED
)
);
printf("about to begin the work, which could take up to %d seconds\n",
4*DESIRED_WORKLOAD_SECONDS*TIME_ARRAY_ELEMENTS
);
check_error("creating major thread (maybe because you\'re not root?)",
pthread_create(&major_thread_id,
&thread_attributes,
major_code,
NULL
)
);
check_error("joining major thread",
pthread_join(major_thread_id,
NULL
)
);
printf("major thread:\n");
for(jndex=0;
jndex<TIME_ARRAY_ELEMENTS;
jndex++
)
{
the_local_time=localtime(major_work_array+jndex);
printf("%02d:%02d:%02d\n",
the_local_time->tm_hour,
the_local_time->tm_min,
the_local_time->tm_sec
);
}
printf("minor thread:\n");
for(jndex=0;
jndex<TIME_ARRAY_ELEMENTS;
jndex++
)
{
the_local_time=localtime(minor_work_array+jndex);
printf("%02d:%02d:%02d\n",
the_local_time->tm_hour,
the_local_time->tm_min,
the_local_time->tm_sec
);
}
return 0;
} /* main() */