O(1) scheduler seems to lock up on sched_FIFO and sched_RR tasks

george anzinger (george@mvista.com)
Wed, 18 Jun 2003 09:47:24 -0700


This is a MIME-formatted message. If you see this text it means that your
E-mail software does not support MIME-formatted messages.

--=_courier-20084-1055955088-0001-2
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

It seems that once a SCHED_FIFO or SCHED_RR tasks gets control it does
not yield to other tasks of higher priority.

Attached is a test program (busyloop) that just loops doing
gettimeofday() for the requested time and a little utility (rt) to run
programs at real time priorities.

Here is an annoted example of the problem:

First, become root then:
> rt 90 bash <-- run bash at priority 90 SCHED_RR
> rt -f 30 busyloop 10 & <-- busyloop 10 at priority 30 SCHED_FIFO

At this point the bash at priority 90 should be available, but is not.
When the 10 second busyloop completes, bash returns.

SCHED_RR is a bit different:
> rt 90 bash <-- run bash at priority 90 SCHED_RR
> rt 30 busyloop 10 & <-- busyloop 10 at priority 30 SCHED_RR

At this point the bash at priority 90 prints the pid and a prompt and
then does not respond for the duration of the busyloop. When the 10
second busyloop completes, bash returns.

The program rt will explain itself if given no parameters.

The program busyloop is just like sleep except that it loops on
getimeofday() instead of sleeping.

This test was run on a 2.5.70 bk9 system...

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml

--=_courier-20084-1055955088-0001-2 Content-Type: text/plain; name="busyloop.c"; charset=iso-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="busyloop.c"

#include <time.h> #include <stdlib.h>

int main(int argc, char *argv[]) { int end_time; struct timeval now;

if (argc < 2) { end_time = 1; }else{ end_time = atoi(argv[1]); } if (!time) { printf("Bad parms, quiting.\n"); return 1; }

gettimeofday(&now);

end_time += now.tv_sec + 1;

do{ gettimeofday(&now);

}while (now.tv_sec < end_time);

printf("bye now.\n"); return 0; }

--=_courier-20084-1055955088-0001-2 Content-Type: text/plain; name="rt.c"; charset=iso-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rt.c"

/* rt - a utility to set the realtime priority and scheduling policy and now also to set nice values. */

/* includes */ #include <stdio.h> #include <stdlib.h> #include <sched.h> #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> #define _GNU_LIBRARY__ #include <getopt.h>

/* defines */

#define RUNSTRING "usage: rt [-f] [-v] prio [--] runstring \n \ or: rt [-f] [-v] -p PID prio\\ \n\n \ where: prio specifies the realtime priority \n \ -f set scheduling policy to SCHED_FIFO \n \ -o set scheduling policy to SCHED_OTHER \n \ In this case prio is a nice value -20<->19 \n \ Use '-- prio' if prio is negative \n \ -v turns on verbose mode. \n \ -p PID specifies an existing process to modify \n \ runstring is a process and parameters \n \ (use '--' if runstring contains options). \n"

#define POLICY(x) x ? x-1 ? "SCHED_RR" : "SCHED_FIFO" : "SCHED_OTHER"

/* prototypes */ void print_usage(char *[]);

/* globals */ int verbose=0; /* 0=none, !0=verbose */

main(int argc, char *argv[]) { struct sched_param prio_struct; int policy = -1; int pid = 0; int pidopt = 0; int nice; int optprobs = 0; /* problems parsing? */ int c; /* generic single character */

/* "standard" option parsing... */ while ( (c=getopt(argc, argv, "+fop:v?")) != EOF) { switch (c) { case 'f': /* set FIFO mode */ policy = SCHED_FIFO; break; case 'o': /* set SCHED_OTHER mode */ policy = SCHED_OTHER; break; case 'p': /* read PID */ sscanf(optarg,"%d",&pid); pidopt=1; break; case 'v': verbose=1; /* verbosity */ break; case '?': /* help? */ printf("%s",RUNSTRING); exit(0); default: /* something went wrong */ optprobs=1; /* we'll deal with this problem later */ break; } }

if (optprobs) { fprintf(stderr,RUNSTRING); exit(1); }

if((argc - optind) < 2-pidopt) { print_usage(argv); }

sscanf(argv[optind], "%d", &(prio_struct.sched_priority));

/* sanity checking... */ if ( (prio_struct.sched_priority > 0) && (policy < 0 ) ) { policy=SCHED_RR; if (verbose) printf("Defaulting sched policy to %s.\n", POLICY(policy)); }

if ( (prio_struct.sched_priority == 0 ) && (policy != SCHED_OTHER) ) { policy=SCHED_OTHER; fprintf(stderr,"Priority of %d implies sched policy of %s.\n", prio_struct.sched_priority, POLICY(policy)); }

//policy = (prio_struct.sched_priority)? policy : SCHED_OTHER; nice = prio_struct.sched_priority; if(policy==SCHED_OTHER) prio_struct.sched_priority = 0; if( sched_setscheduler(pid,policy,&prio_struct)){ perror("Priority out of range"); print_usage(argv); } if(policy==SCHED_OTHER){ if( setpriority(PRIO_PROCESS, pid, nice)){ perror("Nice out of range"); print_usage(argv); } } if ( pid ) exit(0); argv+=optind; /* adjust argv to point to the runstring */ argv++; execvp(argv[0],argv); perror("exec failed.."); }

void print_usage(char * who[]) { printf("%s",RUNSTRING); exit (1); }

--=_courier-20084-1055955088-0001-2--