sched_yield() on "SCHED_FIFO"

Kuniyasu SUZAKI (suzaki@etl.go.jp)
Thu, 29 Jul 1999 13:34:28 +0900


Dear,

This was an article I post comp.os.linux.questions and
comp.os.linux.development.system and I was suggested to post it to
this mailing list.
Please help me.

The action of sched_yield() on real time class "SCHED_FIFO" is strange
on kernel 2.2.5-15 (Redhat 6.0).

The sched_yield() on kernel 2.2.5-15 did not yield the CPU. The
sched_yield() on kernel 2.0.36 yield the CPU. This action was same on
Solaris. What is changed on kernel 2.2.5-15?

I attached the sample program to check sched_yield(). In the program a
process is changed to be SCHED_FIFO by sched_setscheduler() and then
creates a child process by fork(). The child process should take over
the real time class "SCHED_FIFO". And the parent process yields the
CPU by sched_yield(). After that, the child process and parent process
yield each other.

The process is executed by super user. I was thinking this process
could measure the time for context switch on the real time class
"SCHED_FIFO" and it was measured on kernel 2.0.36 and Solaris. But on
2.2.5-15 the parent process didn't yield.

What makes the action strange?

Result on kernel 2.0.36
bash# ./context
Context swicth time 97 us from 148 to 149
Context swicth time 34 us from 149 to 148
Context swicth time 15 us from 148 to 149
Context swicth time 13 us from 149 to 148
Context swicth time 12 us from 148 to 149
Context swicth time 12 us from 149 to 148
Context swicth time 13 us from 148 to 149
Context swicth time 12 us from 149 to 148
Context swicth time 13 us from 148 to 149

Result on kernel 2.2.5-15
[root@bunsaku Linux]# ./context
Context swicth time 34 us from 834 to 834
Context swicth time 6 us from 834 to 834
Context swicth time 5 us from 834 to 834
Context swicth time 5 us from 834 to 834
Context swicth time 5 us from 834 to 834
Context swicth time 5 us from 834 to 834
Context swicth time 5 us from 834 to 834
Context swicth time 5 us from 834 to 834
Context swicth time 5 us from 834 to 834

/*+++++++ from here sample program "context.c" +++++++*/
/*
Linux
gcc -o context context.c

Solaris
gcc -lposix4 -o context context.c
*/

#define _REENTRANT
#include <sys/mman.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/time.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_KEY 3

#include <errno.h>

#define LOOP 10
#define NUMSHM 3
int shmid[NUMSHM];
struct timeval* timelog;
pid_t* pidlist;
int* counter;

void be_rt(pid_t pid, int priority)
{
struct sched_param param;

param.sched_priority = priority;
if(sched_setscheduler(pid,SCHED_FIFO,&param) == -1){
perror("sched_setscheduler");
exit(1);
}
}

int main()
{
int i,rval;
pid_t parent,child;
struct timezone tz;

if ((shmid[0] = shmget(SHM_KEY, sizeof(struct timeval)*(LOOP), IPC_CREAT | 0666)) < 0) {
perror("shmget 0");
exit(1);
}
if ((timelog = (struct timeval*)shmat(shmid[0], NULL, 0)) == (struct timeval*)-1) {
perror("shmat");
exit(1);
}

if ((shmid[1] = shmget(SHM_KEY+1, sizeof(pid_t)*(LOOP), IPC_CREAT | 0666)) < 0) {
perror("shmget 0");
exit(1);
}
if ((pidlist = (pid_t*)shmat(shmid[1], NULL, 0)) == (pid_t*)-1) {
perror("shmat");
exit(1);
}

if ((shmid[2] = shmget(SHM_KEY+2, sizeof(int), IPC_CREAT | 0666)) < 0) {
perror("shmget 0");
exit(1);
}
if ((counter = (int*)shmat(shmid[2], NULL, 0)) == (int*)-1) {
perror("shmat");
exit(1);
}

for(i = 0; i < LOOP; i++) {
timelog[i].tv_sec = 0;
timelog[i].tv_usec = 0;
pidlist[i] = 0;
}
*counter = 0;

if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
perror("mlockall\n");
exit();
};

/***** to be real time process *****/
be_rt(getpid(),10);

parent = getpid();
child = fork();

if(child == 0) { /* child process */
child = getpid();
while(1) {
pidlist[*counter] = child;
gettimeofday(&(timelog[(*counter)++]),&tz);
/*
thr_yield();
yield();
*/
if(sched_yield() == -1) {
perror("sched_yield()");
exit(1);
}
}
}
else { /* parent process */
while(*counter < LOOP) {
pidlist[*counter] = parent;
gettimeofday(&(timelog[(*counter)++]),&tz);
/*
thr_yield();
yield();
*/
if(sched_yield() == -1) {
perror("sched_yield()");
exit(1);
}
}
}
for(i = 0; i < LOOP-1; i++) {
printf("Context swicth time %ld us from %d to %d\n",
((timelog[i+1].tv_sec - timelog[i].tv_sec)*1000*1000+timelog[i+1].tv_usec) - timelog[i].tv_usec,
pidlist[i],pidlist[i+1]);
}

/*** remove shared memory ***/
for(i = 0; i < NUMSHM; i++) {
if (shmctl(shmid[i], IPC_RMID, NULL) < 0) {
perror("shmctl 0");
exit(1);
}
}
/*** kill child process ***/
rval = kill(child,SIGKILL);
if(rval != 0) {
fprintf(stderr,"kill(SIGKILL) error\n");
}
}
/*+++++++ to here +++++++*/
Sincerely yours,
Kuniyasu Suzaki
---------------------------------------------------------------------------
OFFICE ; Electrotechnical Lab. Ministry of International Trade and Industry

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/