1f08c3bdfSopenharmony_ci/******************************************************************************/ 2f08c3bdfSopenharmony_ci/* */ 3f08c3bdfSopenharmony_ci/* Copyright (c) International Business Machines Corp., 2001 */ 4f08c3bdfSopenharmony_ci/* */ 5f08c3bdfSopenharmony_ci/* This program is free software; you can redistribute it and/or modify */ 6f08c3bdfSopenharmony_ci/* it under the terms of the GNU General Public License as published by */ 7f08c3bdfSopenharmony_ci/* the Free Software Foundation; either version 2 of the License, or */ 8f08c3bdfSopenharmony_ci/* (at your option) any later version. */ 9f08c3bdfSopenharmony_ci/* */ 10f08c3bdfSopenharmony_ci/* This program is distributed in the hope that it will be useful, */ 11f08c3bdfSopenharmony_ci/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 12f08c3bdfSopenharmony_ci/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 13f08c3bdfSopenharmony_ci/* the GNU General Public License for more details. */ 14f08c3bdfSopenharmony_ci/* */ 15f08c3bdfSopenharmony_ci/* You should have received a copy of the GNU General Public License */ 16f08c3bdfSopenharmony_ci/* along with this program; if not, write to the Free Software */ 17f08c3bdfSopenharmony_ci/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 18f08c3bdfSopenharmony_ci/* */ 19f08c3bdfSopenharmony_ci/******************************************************************************/ 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci/******************************************************************************/ 22f08c3bdfSopenharmony_ci/* */ 23f08c3bdfSopenharmony_ci/* History: Feb - 21 - 2002 Created - Manoj Iyer, IBM Austin TX. */ 24f08c3bdfSopenharmony_ci/* email: manjo@austin.ibm.com. */ 25f08c3bdfSopenharmony_ci/* */ 26f08c3bdfSopenharmony_ci/* Feb - 25 - 2002 Modified - Manoj Iyer, IBM Austin TX. */ 27f08c3bdfSopenharmony_ci/* - Added structure thread_sched_t. */ 28f08c3bdfSopenharmony_ci/* - Added logic to specify scheduling policy. */ 29f08c3bdfSopenharmony_ci/* */ 30f08c3bdfSopenharmony_ci/* Feb - 25 - 2002 Modified - Manoj Iyer, IBM Austin TX. */ 31f08c3bdfSopenharmony_ci/* - Added header file string.h. */ 32f08c3bdfSopenharmony_ci/* - Removed dead variable ppid from thread_func.*/ 33f08c3bdfSopenharmony_ci/* - Fixed date from 2001 to 2002 in History. */ 34f08c3bdfSopenharmony_ci/* */ 35f08c3bdfSopenharmony_ci/* File: trace_sched.c */ 36f08c3bdfSopenharmony_ci/* */ 37f08c3bdfSopenharmony_ci/* Description: This utility spawns N tasks, each task sets its priority by */ 38f08c3bdfSopenharmony_ci/* making a system call to the scheduler. The thread function */ 39f08c3bdfSopenharmony_ci/* reads the priority that tbe schedular sets for this task and */ 40f08c3bdfSopenharmony_ci/* also reads from /proc the processor this task last executed on*/ 41f08c3bdfSopenharmony_ci/* the information that is gathered by the thread function may */ 42f08c3bdfSopenharmony_ci/* be in real-time. Its only an approximation. */ 43f08c3bdfSopenharmony_ci/* */ 44f08c3bdfSopenharmony_ci/******************************************************************************/ 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci#include <fcntl.h> 47f08c3bdfSopenharmony_ci#include <limits.h> 48f08c3bdfSopenharmony_ci#include <pthread.h> 49f08c3bdfSopenharmony_ci#include <stdio.h> 50f08c3bdfSopenharmony_ci#include <stdlib.h> 51f08c3bdfSopenharmony_ci#include <sched.h> 52f08c3bdfSopenharmony_ci#include <sys/types.h> 53f08c3bdfSopenharmony_ci#include <sys/stat.h> 54f08c3bdfSopenharmony_ci#include <sys/wait.h> 55f08c3bdfSopenharmony_ci#include <sys/time.h> 56f08c3bdfSopenharmony_ci#include <unistd.h> 57f08c3bdfSopenharmony_ci#include <string.h> 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_civoid noprintf(char *string, ...) 60f08c3bdfSopenharmony_ci{ 61f08c3bdfSopenharmony_ci} 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ci#ifdef DEBUG /* compile with this flag for debug, use dprt in code */ 64f08c3bdfSopenharmony_ci#define dprt printf 65f08c3bdfSopenharmony_ci#else 66f08c3bdfSopenharmony_ci#define dprt noprintf 67f08c3bdfSopenharmony_ci#endif 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci#ifndef PID_MAX 70f08c3bdfSopenharmony_ci#define PID_MAX 0x8000 71f08c3bdfSopenharmony_ci#endif 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci#define MAXT 100 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci#ifdef PTHREAD_THREADS_MAX 76f08c3bdfSopenharmony_ci#define PIDS PTHREAD_THREADS_MAX /* maximum thread allowed. */ 77f08c3bdfSopenharmony_ci#elif defined(PID_MAX_DEFAULT) 78f08c3bdfSopenharmony_ci#define PIDS PID_MAX_DEFAULT /* maximum pids allowed. */ 79f08c3bdfSopenharmony_ci#else 80f08c3bdfSopenharmony_ci#define PIDS PID_MAX /* alternative way maximum pids may be defined */ 81f08c3bdfSopenharmony_ci#endif 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci#define UP 1 /* assume UP if no SMP value is specified. */ 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci#define OPT_MISSING(prog, opt) do{\ 86f08c3bdfSopenharmony_ci fprintf(stderr, "%s: option -%c ", prog, opt); \ 87f08c3bdfSopenharmony_ci fprintf(stderr, "requires an argument\n"); \ 88f08c3bdfSopenharmony_ci usage(prog); \ 89f08c3bdfSopenharmony_ci } while (0) 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci#define SAFE_FREE(p) { if (p) { free(p); (p)=NULL; } } 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_citypedef struct { /* contains priority and CPU info of the task. */ 94f08c3bdfSopenharmony_ci int exp_prio; /* priority that we wish to set. */ 95f08c3bdfSopenharmony_ci int act_prio; /* priority set by the scheduler. */ 96f08c3bdfSopenharmony_ci int proc_num; /* last processor on which this task executed. */ 97f08c3bdfSopenharmony_ci int procs_id; /* pid of this task. */ 98f08c3bdfSopenharmony_ci int s_policy; /* scheduling policy for the task. */ 99f08c3bdfSopenharmony_ci} thread_sched_t; 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ciint verbose = 0; /* set verbose printing, makes output look ugly! */ 102f08c3bdfSopenharmony_ci 103f08c3bdfSopenharmony_ci/******************************************************************************/ 104f08c3bdfSopenharmony_ci/* */ 105f08c3bdfSopenharmony_ci/* Function: usage */ 106f08c3bdfSopenharmony_ci/* */ 107f08c3bdfSopenharmony_ci/* Description: Print the usage message. */ 108f08c3bdfSopenharmony_ci/* */ 109f08c3bdfSopenharmony_ci/* Return: exits with -1 */ 110f08c3bdfSopenharmony_ci/* */ 111f08c3bdfSopenharmony_ci/******************************************************************************/ 112f08c3bdfSopenharmony_civoid usage(char *progname) 113f08c3bdfSopenharmony_ci{ /* name of this program */ 114f08c3bdfSopenharmony_ci fprintf(stderr, 115f08c3bdfSopenharmony_ci "Usage: %s -c NCPU -h -p [fifo:rr:other] -t THREADS -v\n" 116f08c3bdfSopenharmony_ci "\t -c Number of CUPS in the machine. User MUST provide\n" 117f08c3bdfSopenharmony_ci "\t -h Help!\n" 118f08c3bdfSopenharmony_ci "\t -p Scheduling policy, choice: fifo, rr, other. Default: fifo\n" 119f08c3bdfSopenharmony_ci "\t -t Number of threads to create. Default: %d\n" 120f08c3bdfSopenharmony_ci "\t -v Verbose out put, print ugly!. Default: OFF\n", 121f08c3bdfSopenharmony_ci progname, MAXT); 122f08c3bdfSopenharmony_ci exit(-1); 123f08c3bdfSopenharmony_ci} 124f08c3bdfSopenharmony_ci 125f08c3bdfSopenharmony_ci/******************************************************************************/ 126f08c3bdfSopenharmony_ci/* */ 127f08c3bdfSopenharmony_ci/* Function: get_proc_num */ 128f08c3bdfSopenharmony_ci/* */ 129f08c3bdfSopenharmony_ci/* Description: Function reads the proc filesystem file /proc/<PID>/stat */ 130f08c3bdfSopenharmony_ci/* gets the CPU number this process last executed on and returns */ 131f08c3bdfSopenharmony_ci/* Some hard assumptions were made regarding buffer sizes. */ 132f08c3bdfSopenharmony_ci/* */ 133f08c3bdfSopenharmony_ci/* Return: exits with -1 - on error */ 134f08c3bdfSopenharmony_ci/* CPU number - on success */ 135f08c3bdfSopenharmony_ci/* */ 136f08c3bdfSopenharmony_ci/******************************************************************************/ 137f08c3bdfSopenharmony_cistatic int get_proc_num(void) 138f08c3bdfSopenharmony_ci{ 139f08c3bdfSopenharmony_ci int fd = -1; /* file descriptor of the /proc/<pid>/stat file. */ 140f08c3bdfSopenharmony_ci int fsize = -1; /* size of the /proc/<pid>/stat file. */ 141f08c3bdfSopenharmony_ci char filename[256]; /* buffer to hold the string /proc/<pid>/stat. */ 142f08c3bdfSopenharmony_ci char fbuff[512]; /* contains the contents of the stat file. */ 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci /* get the name of the stat file for this process */ 145f08c3bdfSopenharmony_ci sprintf(filename, "/proc/%d/stat", getpid()); 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci /* open the stat file and read the contents to a buffer */ 148f08c3bdfSopenharmony_ci if ((fd = open(filename, O_RDONLY)) == -1) { 149f08c3bdfSopenharmony_ci perror("get_proc_num(): open()"); 150f08c3bdfSopenharmony_ci return -1; 151f08c3bdfSopenharmony_ci } 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci usleep(6); 154f08c3bdfSopenharmony_ci sched_yield(); 155f08c3bdfSopenharmony_ci 156f08c3bdfSopenharmony_ci if ((fsize = read(fd, fbuff, 512)) == -1) { 157f08c3bdfSopenharmony_ci perror("main(): read()"); 158f08c3bdfSopenharmony_ci return -1; 159f08c3bdfSopenharmony_ci } 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_ci close(fd); 162f08c3bdfSopenharmony_ci /* return the processor number last executed on. */ 163f08c3bdfSopenharmony_ci return atoi(&fbuff[fsize - 2]); 164f08c3bdfSopenharmony_ci} 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_ci/******************************************************************************/ 167f08c3bdfSopenharmony_ci/* */ 168f08c3bdfSopenharmony_ci/* Function: thread_func */ 169f08c3bdfSopenharmony_ci/* */ 170f08c3bdfSopenharmony_ci/* Description: This function is executed in the context of the new task that */ 171f08c3bdfSopenharmony_ci/* pthread_createi() will spawn. The (thread) task will get the */ 172f08c3bdfSopenharmony_ci/* minimum and maximum static priority for this system, set the */ 173f08c3bdfSopenharmony_ci/* priority of the current task to a random priority value if */ 174f08c3bdfSopenharmony_ci/* the policy set if SCHED_FIFO or SCHED_RR. The priority if this*/ 175f08c3bdfSopenharmony_ci/* task that was assigned by the scheduler is got from making the*/ 176f08c3bdfSopenharmony_ci/* system call to sched_getscheduler(). The CPU number on which */ 177f08c3bdfSopenharmony_ci/* the task was last seen is also recorded. All the above data is*/ 178f08c3bdfSopenharmony_ci/* returned to the calling routine in a structure thread_sched_t.*/ 179f08c3bdfSopenharmony_ci/* */ 180f08c3bdfSopenharmony_ci/* Input: thread_sched_t */ 181f08c3bdfSopenharmony_ci/* s_policy - scheduling policy for the task. */ 182f08c3bdfSopenharmony_ci/* */ 183f08c3bdfSopenharmony_ci/* Return: thread_sched_t - on success. */ 184f08c3bdfSopenharmony_ci/* exp_prio - random priority value to set. */ 185f08c3bdfSopenharmony_ci/* act_prio - priority set by the scheduler. */ 186f08c3bdfSopenharmony_ci/* proc_num - CPU number on which this task last executed. */ 187f08c3bdfSopenharmony_ci/* procs_id - pid of this task. */ 188f08c3bdfSopenharmony_ci/* */ 189f08c3bdfSopenharmony_ci/* -1 - on error. */ 190f08c3bdfSopenharmony_ci/* */ 191f08c3bdfSopenharmony_ci/******************************************************************************/ 192f08c3bdfSopenharmony_civoid *thread_func(void *args) 193f08c3bdfSopenharmony_ci{ /* arguments to the thread function */ 194f08c3bdfSopenharmony_ci static int max_priority; /* max possible priority for a process. */ 195f08c3bdfSopenharmony_ci static int min_priority; /* min possible priority for a process. */ 196f08c3bdfSopenharmony_ci static int set_priority; /* set the priority of the proc by this value. */ 197f08c3bdfSopenharmony_ci static int get_priority; /* get the priority that is set for this proc. */ 198f08c3bdfSopenharmony_ci static int procnum; /* processor number last executed on. */ 199f08c3bdfSopenharmony_ci static int sched_policy; /* scheduling policy as set by user/default */ 200f08c3bdfSopenharmony_ci struct sched_param ssp; /* set schedule priority. */ 201f08c3bdfSopenharmony_ci struct sched_param gsp; /* gsp schedule priority. */ 202f08c3bdfSopenharmony_ci struct timeval tptr; /* tptr.tv_usec will be used to seed srand. */ 203f08c3bdfSopenharmony_ci thread_sched_t *locargptr = /* local ptr to the arguments. */ 204f08c3bdfSopenharmony_ci (thread_sched_t *) args; 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci /* Get the system max and min static priority for a process. */ 207f08c3bdfSopenharmony_ci if (((max_priority = sched_get_priority_max(SCHED_FIFO)) == -1) || 208f08c3bdfSopenharmony_ci ((min_priority = sched_get_priority_min(SCHED_FIFO)) == -1)) { 209f08c3bdfSopenharmony_ci fprintf(stderr, "failed to get static priority range\n"); 210f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with -1\n", getpid()); 211f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 212f08c3bdfSopenharmony_ci } 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci if ((sched_policy = locargptr->s_policy) == SCHED_OTHER) 215f08c3bdfSopenharmony_ci ssp.sched_priority = 0; 216f08c3bdfSopenharmony_ci else { 217f08c3bdfSopenharmony_ci /* Set a random value between max_priority and min_priority */ 218f08c3bdfSopenharmony_ci gettimeofday(&tptr, NULL); 219f08c3bdfSopenharmony_ci srand((unsigned int)tptr.tv_usec); 220f08c3bdfSopenharmony_ci set_priority = (min_priority + (int)((float)max_priority 221f08c3bdfSopenharmony_ci * rand() / (RAND_MAX + 222f08c3bdfSopenharmony_ci 1.0))); 223f08c3bdfSopenharmony_ci ssp.sched_priority = set_priority; 224f08c3bdfSopenharmony_ci } 225f08c3bdfSopenharmony_ci 226f08c3bdfSopenharmony_ci /* give other threads a chance */ 227f08c3bdfSopenharmony_ci usleep(8); 228f08c3bdfSopenharmony_ci 229f08c3bdfSopenharmony_ci /* set a random priority value and check if this value was honoured. */ 230f08c3bdfSopenharmony_ci if ((sched_setscheduler(getpid(), sched_policy, &ssp)) == -1) { 231f08c3bdfSopenharmony_ci perror("main(): sched_setscheduler()"); 232f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with -1\n", getpid()); 233f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 234f08c3bdfSopenharmony_ci } 235f08c3bdfSopenharmony_ci 236f08c3bdfSopenharmony_ci /* processor number this process last executed on */ 237f08c3bdfSopenharmony_ci if ((procnum = get_proc_num()) == -1) { 238f08c3bdfSopenharmony_ci fprintf(stderr, "main(): get_proc_num() failed\n"); 239f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with -1\n", getpid()); 240f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 241f08c3bdfSopenharmony_ci } 242f08c3bdfSopenharmony_ci 243f08c3bdfSopenharmony_ci if ((get_priority = sched_getparam(getpid(), &gsp)) == -1) { 244f08c3bdfSopenharmony_ci perror("main(): sched_setscheduler()"); 245f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with -1\n", getpid()); 246f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 247f08c3bdfSopenharmony_ci } 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci /* processor number this process last executed on */ 250f08c3bdfSopenharmony_ci if ((procnum = get_proc_num()) == -1) { 251f08c3bdfSopenharmony_ci fprintf(stderr, "main(): get_proc_num() failed\n"); 252f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with -1\n", getpid()); 253f08c3bdfSopenharmony_ci pthread_exit((void *)-1); 254f08c3bdfSopenharmony_ci } 255f08c3bdfSopenharmony_ci 256f08c3bdfSopenharmony_ci if (verbose) { 257f08c3bdfSopenharmony_ci fprintf(stdout, 258f08c3bdfSopenharmony_ci "PID of this task = %d\n" 259f08c3bdfSopenharmony_ci "Max priority = %d\n" 260f08c3bdfSopenharmony_ci "Min priority = %d\n" 261f08c3bdfSopenharmony_ci "Expected priority = %d\n" 262f08c3bdfSopenharmony_ci "Actual assigned priority = %d\n" 263f08c3bdfSopenharmony_ci "Processor last execed on = %d\n\n", getpid(), 264f08c3bdfSopenharmony_ci max_priority, min_priority, set_priority, 265f08c3bdfSopenharmony_ci gsp.sched_priority, procnum); 266f08c3bdfSopenharmony_ci } 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_ci locargptr->exp_prio = set_priority; 269f08c3bdfSopenharmony_ci locargptr->act_prio = gsp.sched_priority; 270f08c3bdfSopenharmony_ci locargptr->proc_num = procnum; 271f08c3bdfSopenharmony_ci locargptr->procs_id = getpid(); 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci dprt("pid[%d]: exiting with %ld\n", getpid(), locargptr); 274f08c3bdfSopenharmony_ci pthread_exit((void *)locargptr); 275f08c3bdfSopenharmony_ci} 276f08c3bdfSopenharmony_ci 277f08c3bdfSopenharmony_ci/******************************************************************************/ 278f08c3bdfSopenharmony_ci/* */ 279f08c3bdfSopenharmony_ci/* Function: main */ 280f08c3bdfSopenharmony_ci/* */ 281f08c3bdfSopenharmony_ci/* Description: Entry point of the program, parse options, check for their */ 282f08c3bdfSopenharmony_ci/* validity, spawn N tasks, wait for them to return, in the end */ 283f08c3bdfSopenharmony_ci/* print all the data that the thiread function collected. */ 284f08c3bdfSopenharmony_ci/* */ 285f08c3bdfSopenharmony_ci/* Return: exits with -1 - on error. */ 286f08c3bdfSopenharmony_ci/* exits with 0 - on success. */ 287f08c3bdfSopenharmony_ci/* */ 288f08c3bdfSopenharmony_ci/******************************************************************************/ 289f08c3bdfSopenharmony_ciint main(int argc, /* number of input parameters. */ 290f08c3bdfSopenharmony_ci char **argv) 291f08c3bdfSopenharmony_ci{ /* pointer to the command line arguments. */ 292f08c3bdfSopenharmony_ci int c; /* command line options. */ 293f08c3bdfSopenharmony_ci int proc_ndx; /* number of time to repete the loop. */ 294f08c3bdfSopenharmony_ci int pid_ndx; /* number of time to repete the loop. */ 295f08c3bdfSopenharmony_ci int num_cpus = UP; /* assume machine is an UP machine. */ 296f08c3bdfSopenharmony_ci int num_thrd = MAXT; /* number of threads to create. */ 297f08c3bdfSopenharmony_ci int thrd_ndx; /* index into the array of threads. */ 298f08c3bdfSopenharmony_ci int exp_prio[PIDS]; /* desired priority, random value. */ 299f08c3bdfSopenharmony_ci int act_prio[PIDS]; /* priority actually set. */ 300f08c3bdfSopenharmony_ci int gen_pid[PIDS]; /* pid of the processes on this processor. */ 301f08c3bdfSopenharmony_ci int proc_id[PIDS]; /* id of the processor last execed on. */ 302f08c3bdfSopenharmony_ci int spcy = SCHED_FIFO; /* scheduling policy for the tasks. */ 303f08c3bdfSopenharmony_ci pthread_t thid[PIDS]; /* pids of process or threads spawned */ 304f08c3bdfSopenharmony_ci thread_sched_t *chld_args; /* arguments to funcs execed by child process. */ 305f08c3bdfSopenharmony_ci thread_sched_t *status; /* exit status for light weight process. */ 306f08c3bdfSopenharmony_ci extern char *optarg; /* arguments passed to each option. */ 307f08c3bdfSopenharmony_ci thread_sched_t **args_table; /* pointer table of arguments address */ 308f08c3bdfSopenharmony_ci thread_sched_t **status_table; /*pointer table of status address */ 309f08c3bdfSopenharmony_ci 310f08c3bdfSopenharmony_ci if (getuid() != 0) { 311f08c3bdfSopenharmony_ci fprintf(stderr, 312f08c3bdfSopenharmony_ci "ERROR: Only root user can run this program.\n"); 313f08c3bdfSopenharmony_ci usage(argv[0]); 314f08c3bdfSopenharmony_ci } 315f08c3bdfSopenharmony_ci 316f08c3bdfSopenharmony_ci if (argc < 2) { 317f08c3bdfSopenharmony_ci fprintf(stderr, 318f08c3bdfSopenharmony_ci "ERROR: Enter a value for the number of CPUS\n"); 319f08c3bdfSopenharmony_ci usage(argv[0]); 320f08c3bdfSopenharmony_ci } 321f08c3bdfSopenharmony_ci 322f08c3bdfSopenharmony_ci while ((c = getopt(argc, argv, "c:hp:t:v")) != -1) { 323f08c3bdfSopenharmony_ci switch (c) { 324f08c3bdfSopenharmony_ci case 'c': /* number of processors. no default. */ 325f08c3bdfSopenharmony_ci if ((num_cpus = atoi(optarg)) == 0) 326f08c3bdfSopenharmony_ci OPT_MISSING(argv[0], optopt); 327f08c3bdfSopenharmony_ci else if (num_cpus < 0) { 328f08c3bdfSopenharmony_ci fprintf(stdout, 329f08c3bdfSopenharmony_ci "WARNING: Bad argument -p %d. Using default\n", 330f08c3bdfSopenharmony_ci num_cpus); 331f08c3bdfSopenharmony_ci num_cpus = UP; 332f08c3bdfSopenharmony_ci } 333f08c3bdfSopenharmony_ci /* MAXT threads per cpu. */ 334f08c3bdfSopenharmony_ci num_thrd = num_thrd * num_cpus; 335f08c3bdfSopenharmony_ci break; 336f08c3bdfSopenharmony_ci case 'h': /* usage message */ 337f08c3bdfSopenharmony_ci usage(argv[0]); 338f08c3bdfSopenharmony_ci break; 339f08c3bdfSopenharmony_ci case 'p': /* schedular policy. default SCHED_FIFO */ 340f08c3bdfSopenharmony_ci if (strncmp(optarg, "fifo", 4) == 0) 341f08c3bdfSopenharmony_ci spcy = SCHED_FIFO; 342f08c3bdfSopenharmony_ci else if (strncmp(optarg, "rr", 2) == 0) 343f08c3bdfSopenharmony_ci spcy = SCHED_RR; 344f08c3bdfSopenharmony_ci else if (strncmp(optarg, "other", 5) == 0) 345f08c3bdfSopenharmony_ci spcy = SCHED_OTHER; 346f08c3bdfSopenharmony_ci else { 347f08c3bdfSopenharmony_ci fprintf(stderr, 348f08c3bdfSopenharmony_ci "ERROR: Unrecognized scheduler policy, " 349f08c3bdfSopenharmony_ci "using default\n"); 350f08c3bdfSopenharmony_ci usage(argv[0]); 351f08c3bdfSopenharmony_ci } 352f08c3bdfSopenharmony_ci break; 353f08c3bdfSopenharmony_ci case 't': /* input how many threads to create */ 354f08c3bdfSopenharmony_ci if ((num_thrd = atoi(optarg)) == 0) 355f08c3bdfSopenharmony_ci OPT_MISSING(argv[0], optopt); 356f08c3bdfSopenharmony_ci else if (num_thrd < 0) { 357f08c3bdfSopenharmony_ci fprintf(stderr, 358f08c3bdfSopenharmony_ci "WARNING: Bad argument -t %d. Using default\n", 359f08c3bdfSopenharmony_ci num_thrd); 360f08c3bdfSopenharmony_ci num_thrd = MAXT; 361f08c3bdfSopenharmony_ci } else if (num_thrd > PIDS) { 362f08c3bdfSopenharmony_ci fprintf(stderr, 363f08c3bdfSopenharmony_ci "WARNING: -t %d exceeds maximum number of allowed pids" 364f08c3bdfSopenharmony_ci " %d\n Setting number of threads to %d\n", 365f08c3bdfSopenharmony_ci num_thrd, PIDS, PIDS - 1000); 366f08c3bdfSopenharmony_ci num_thrd = (PIDS - 1000); 367f08c3bdfSopenharmony_ci } 368f08c3bdfSopenharmony_ci break; 369f08c3bdfSopenharmony_ci case 'v': /* verbose out put, make output look ugly! */ 370f08c3bdfSopenharmony_ci verbose = 1; 371f08c3bdfSopenharmony_ci break; 372f08c3bdfSopenharmony_ci default: 373f08c3bdfSopenharmony_ci usage(argv[0]); 374f08c3bdfSopenharmony_ci break; 375f08c3bdfSopenharmony_ci } 376f08c3bdfSopenharmony_ci } 377f08c3bdfSopenharmony_ci 378f08c3bdfSopenharmony_ci /* create num_thrd number of threads. */ 379f08c3bdfSopenharmony_ci args_table = malloc(num_thrd * sizeof(thread_sched_t *)); 380f08c3bdfSopenharmony_ci if (!args_table) { 381f08c3bdfSopenharmony_ci perror("main(): malloc failed"); 382f08c3bdfSopenharmony_ci exit(-1); 383f08c3bdfSopenharmony_ci } 384f08c3bdfSopenharmony_ci for (thrd_ndx = 0; thrd_ndx < num_thrd; thrd_ndx++) { 385f08c3bdfSopenharmony_ci args_table[thrd_ndx] = malloc(sizeof(thread_sched_t)); 386f08c3bdfSopenharmony_ci if (!args_table[thrd_ndx]) { 387f08c3bdfSopenharmony_ci perror("main(): malloc failed"); 388f08c3bdfSopenharmony_ci exit(-1); 389f08c3bdfSopenharmony_ci } 390f08c3bdfSopenharmony_ci chld_args = args_table[thrd_ndx]; 391f08c3bdfSopenharmony_ci chld_args->s_policy = spcy; 392f08c3bdfSopenharmony_ci if (pthread_create(&thid[thrd_ndx], NULL, thread_func, 393f08c3bdfSopenharmony_ci chld_args)) { 394f08c3bdfSopenharmony_ci fprintf(stderr, "ERROR: creating task number: %d\n", 395f08c3bdfSopenharmony_ci thrd_ndx); 396f08c3bdfSopenharmony_ci perror("main(): pthread_create()"); 397f08c3bdfSopenharmony_ci exit(-1); 398f08c3bdfSopenharmony_ci } 399f08c3bdfSopenharmony_ci if (verbose) 400f08c3bdfSopenharmony_ci fprintf(stdout, "Created thread[%d]\n", thrd_ndx); 401f08c3bdfSopenharmony_ci usleep(9); 402f08c3bdfSopenharmony_ci sched_yield(); 403f08c3bdfSopenharmony_ci } 404f08c3bdfSopenharmony_ci 405f08c3bdfSopenharmony_ci /* wait for the children to terminate */ 406f08c3bdfSopenharmony_ci status_table = malloc(num_thrd * sizeof(thread_sched_t *)); 407f08c3bdfSopenharmony_ci if (!status_table) { 408f08c3bdfSopenharmony_ci perror("main(): malloc failed"); 409f08c3bdfSopenharmony_ci exit(-1); 410f08c3bdfSopenharmony_ci } 411f08c3bdfSopenharmony_ci for (thrd_ndx = 0; thrd_ndx < num_thrd; thrd_ndx++) { 412f08c3bdfSopenharmony_ci status_table[thrd_ndx] = malloc(sizeof(thread_sched_t)); 413f08c3bdfSopenharmony_ci if (!status_table[thrd_ndx]) { 414f08c3bdfSopenharmony_ci perror("main(): malloc failed"); 415f08c3bdfSopenharmony_ci exit(-1); 416f08c3bdfSopenharmony_ci } 417f08c3bdfSopenharmony_ci status = status_table[thrd_ndx]; 418f08c3bdfSopenharmony_ci if (pthread_join(thid[thrd_ndx], (void **)&status)) { 419f08c3bdfSopenharmony_ci perror("main(): pthread_join()"); 420f08c3bdfSopenharmony_ci exit(-1); 421f08c3bdfSopenharmony_ci } else { 422f08c3bdfSopenharmony_ci if (status == (thread_sched_t *) - 1) { 423f08c3bdfSopenharmony_ci fprintf(stderr, 424f08c3bdfSopenharmony_ci "thread [%d] - process exited with exit code -1\n", 425f08c3bdfSopenharmony_ci thrd_ndx); 426f08c3bdfSopenharmony_ci exit(-1); 427f08c3bdfSopenharmony_ci } else { 428f08c3bdfSopenharmony_ci exp_prio[thrd_ndx] = status->exp_prio; 429f08c3bdfSopenharmony_ci act_prio[thrd_ndx] = status->act_prio; 430f08c3bdfSopenharmony_ci proc_id[thrd_ndx] = status->proc_num; 431f08c3bdfSopenharmony_ci gen_pid[thrd_ndx] = status->procs_id; 432f08c3bdfSopenharmony_ci } 433f08c3bdfSopenharmony_ci } 434f08c3bdfSopenharmony_ci SAFE_FREE(args_table[thrd_ndx]); 435f08c3bdfSopenharmony_ci SAFE_FREE(status_table[thrd_ndx]); 436f08c3bdfSopenharmony_ci usleep(10); 437f08c3bdfSopenharmony_ci } 438f08c3bdfSopenharmony_ci 439f08c3bdfSopenharmony_ci if (verbose) { 440f08c3bdfSopenharmony_ci fprintf(stdout, 441f08c3bdfSopenharmony_ci "Number of tasks spawned: %d\n" 442f08c3bdfSopenharmony_ci "Number of CPUs: %d\n" 443f08c3bdfSopenharmony_ci "Scheduling policy: %d\n", num_thrd, num_cpus, 444f08c3bdfSopenharmony_ci spcy); 445f08c3bdfSopenharmony_ci } 446f08c3bdfSopenharmony_ci 447f08c3bdfSopenharmony_ci SAFE_FREE(args_table); 448f08c3bdfSopenharmony_ci SAFE_FREE(status_table); 449f08c3bdfSopenharmony_ci 450f08c3bdfSopenharmony_ci for (proc_ndx = 0; proc_ndx < num_cpus; proc_ndx++) { 451f08c3bdfSopenharmony_ci fprintf(stdout, "For processor number = %d\n", proc_ndx); 452f08c3bdfSopenharmony_ci fprintf(stdout, "%s\n", "==========================="); 453f08c3bdfSopenharmony_ci for (pid_ndx = 0; pid_ndx < num_thrd; pid_ndx++) { 454f08c3bdfSopenharmony_ci if (proc_id[pid_ndx] == proc_ndx) 455f08c3bdfSopenharmony_ci fprintf(stdout, 456f08c3bdfSopenharmony_ci "pid of task = %d priority requested = %d" 457f08c3bdfSopenharmony_ci " priority assigned by scheduler = %d\n", 458f08c3bdfSopenharmony_ci gen_pid[pid_ndx], exp_prio[pid_ndx], 459f08c3bdfSopenharmony_ci act_prio[pid_ndx]); 460f08c3bdfSopenharmony_ci } 461f08c3bdfSopenharmony_ci } 462f08c3bdfSopenharmony_ci exit(0); 463f08c3bdfSopenharmony_ci} 464