/* * from agruen - 2009 05 28 * * Test time slices given to each process */ #include #include #include #include #include #include #include #include #include #include #undef WITH_PER_PROCESS_SLICES struct msg { long mtype; long nivcsw; long utime; }; int msqid; void report_to_parent(int dummy) { static long old_nivcsw, old_utime; long utime; struct rusage usage; struct msg msg; getrusage(RUSAGE_SELF, &usage); utime = usage.ru_utime.tv_sec * 1000000 + usage.ru_utime.tv_usec; msg.mtype = 1; msg.nivcsw = usage.ru_nivcsw - old_nivcsw; msg.utime = utime - old_utime; msgsnd(msqid, &msg, sizeof(msg) - sizeof(long), 0); old_nivcsw = usage.ru_nivcsw; old_utime = utime; } void worker(void) { struct sigaction sa; sa.sa_handler = report_to_parent; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGALRM, &sa, NULL); while (1) /* do nothing */ ; } void sleeper(void) { while (1) { usleep(1000); } } int main(int argc, char *argv[]) { int n, nproc; pid_t *pid; if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } msqid = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR); nproc = atoi(argv[1]); pid = malloc(nproc * sizeof(pid_t)); for (n = 0; n < nproc; n++) { pid[n] = fork(); if (pid[n] == 0) worker(); } /* Fork sleeper(s) */ for (n = 0; n < (nproc + 7)/8; n++) if (fork() == 0) sleeper(); for(;;) { long avg_slice = 0, avg_utime = 0; sleep(1); for (n = 0; n < nproc; n++) kill(pid[n], SIGALRM); for (n = 0; n < nproc; n++) { struct msg msg; double slice; msgrcv(msqid, &msg, sizeof(msg) - sizeof(long), 0, 0); slice = 0.001 * msg.utime / (msg.nivcsw ? msg.nivcsw : 1); #ifdef WITH_PER_PROCESS_SLICES printf("%6.1f ", slice); #endif avg_slice += slice; avg_utime += msg.utime; } printf(" avg slice: %5.2f utime: %f", (double) avg_slice / nproc, (double) avg_utime / nproc); printf("\n"); } return 0; }