Example #1
0
File: 1-6.c Project: 1587/ltp
int main(void)
{
	pthread_attr_t attr;
	pthread_t th;
	struct params p;
	int ret;
	unsigned int i;

	ret = set_affinity_single();
	if (ret) {
		n_threads = get_ncpu();
		if (n_threads == -1) {
			printf("Cannot get number of CPUs\n");
			return PTS_UNRESOLVED;
		}
		printf("INFO: Affinity not supported, running %i threads.\n",
		       n_threads);
	} else {
		printf("INFO: Affinity works, will use only one thread.\n");
		n_threads = 1;
	}

	for (i = 0; i < ARRAY_SIZE(tcases); i++) {
		p.sched_policy = tcases[i].sched_policy;
		p.sched_priority = get_prio(&tcases[i]);

		init_attr(&attr, p.sched_policy, p.sched_priority);

		printf("INFO: Testing %s prio %i\n",
		       sched_policy_name(p.sched_policy), p.sched_priority);

		ret = pthread_create(&th, &attr, do_test, &p);
		if (ret) {
			fprintf(stderr, "pthread_create(): %s\n", strerror(ret));
			return PTS_UNRESOLVED;
		}

		pthread_join(th, NULL);

		pthread_attr_destroy(&attr);
	}

	printf("Test PASSED\n");
	return 0;
}
Example #2
0
/* We hold the allocation lock.	*/
void GC_thr_init(void)
{
#   ifndef GC_DARWIN_THREADS
        int dummy;
#   endif
    GC_thread t;

    if (GC_thr_initialized) return;
    GC_thr_initialized = TRUE;
    
#   ifdef HANDLE_FORK
      /* Prepare for a possible fork.	*/
        pthread_atfork(GC_fork_prepare_proc, GC_fork_parent_proc,
	  	       GC_fork_child_proc);
#   endif /* HANDLE_FORK */
#   if defined(INCLUDE_LINUX_THREAD_DESCR)
      /* Explicitly register the region including the address 		*/
      /* of a thread local variable.  This should include thread	*/
      /* locals for the main thread, except for those allocated		*/
      /* in response to dlopen calls.					*/  
	{
	  ptr_t thread_local_addr = (ptr_t)(&dummy_thread_local);
	  ptr_t main_thread_start, main_thread_end;
          if (!GC_enclosing_mapping(thread_local_addr, &main_thread_start,
				    &main_thread_end)) {
	    ABORT("Failed to find mapping for main thread thread locals");
	  }
	  GC_add_roots_inner(main_thread_start, main_thread_end, FALSE);
	}
#   endif
    /* Add the initial thread, so we can stop it.	*/
      t = GC_new_thread(pthread_self());
#     ifdef GC_DARWIN_THREADS
         t -> stop_info.mach_thread = mach_thread_self();
#     else
         t -> stop_info.stack_ptr = (ptr_t)(&dummy);
#     endif
      t -> flags = DETACHED | MAIN_THREAD;

    GC_stop_init();

    /* Set GC_nprocs.  */
      {
	char * nprocs_string = GETENV("GC_NPROCS");
	GC_nprocs = -1;
	if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string);
      }
      if (GC_nprocs <= 0) {
#       if defined(GC_HPUX_THREADS)
	  GC_nprocs = pthread_num_processors_np();
#       endif
#	if defined(GC_OSF1_THREADS) || defined(GC_AIX_THREADS) \
	   || defined(GC_SOLARIS_THREADS) || defined(GC_GNU_THREADS)
	  GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN);
	  if (GC_nprocs <= 0) GC_nprocs = 1;
#	endif
#       if defined(GC_IRIX_THREADS)
	  GC_nprocs = sysconf(_SC_NPROC_ONLN);
	  if (GC_nprocs <= 0) GC_nprocs = 1;
#       endif
#       if defined(GC_NETBSD_THREADS)
	  GC_nprocs = get_ncpu();
#       endif
#       if defined(GC_OPENBSD_THREADS)
	  GC_nprocs = 1;
#       endif
#       if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS)
	  int ncpus = 1;
	  size_t len = sizeof(ncpus);
	  sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
Example #3
0
int
main(int argc, char **argv)
{
    int			c;
    int			sts;
    int			samples;
    int			pauseFlag = 0;
    int			lines = 0;
    char		*source;
    const char		*host;
    info_t		info;		/* values to report each sample */
    char		timebuf[26];	/* for pmCtime result */

    setlinebuf(stdout);

    while ((c = pmGetOptions(argc, argv, &opts)) != EOF) {
	switch (c) {
	case 'P':
	    pauseFlag++;
	    break;
	default:
	    opts.errors++;
	    break;
	}
    }

    if (pauseFlag && opts.context != PM_CONTEXT_ARCHIVE) {
	pmprintf("%s: pause can only be used with archives\n", pmProgname);
	opts.errors++;
    }

    if (opts.errors || opts.optind < argc - 1) {
	pmUsageMessage(&opts);
	exit(1);
    }

    if (opts.context == PM_CONTEXT_ARCHIVE) {
	source = opts.archives[0];
    } else if (opts.context == PM_CONTEXT_HOST) {
	source = opts.hosts[0];
    } else {
	opts.context = PM_CONTEXT_HOST;
	source = "local:";
    }

    if ((sts = c = pmNewContext(opts.context, source)) < 0) {
	if (opts.context == PM_CONTEXT_HOST)
	    fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
		    pmProgname, source, pmErrStr(sts));
	else
	    fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
		    pmProgname, source, pmErrStr(sts));
	exit(1);
    }

    /* complete TZ and time window option (origin) setup */
    if (pmGetContextOptions(c, &opts)) {
	pmflush();
	exit(1);
    }

    host = pmGetContextHostName(c);
    ncpu = get_ncpu();

    if ((opts.context == PM_CONTEXT_ARCHIVE) &&
	(opts.start.tv_sec != 0 || opts.start.tv_usec != 0)) {
	if ((sts = pmSetMode(PM_MODE_FORW, &opts.start, 0)) < 0) {
	    fprintf(stderr, "%s: pmSetMode failed: %s\n",
		    pmProgname, pmErrStr(sts));
	    exit(1);
	}
    }

    get_sample(&info);

    /* set a default sampling interval if none has been requested */
    if (opts.interval.tv_sec == 0 && opts.interval.tv_usec == 0)
	opts.interval.tv_sec = 5;

    /* set sampling loop termination via the command line options */
    samples = opts.samples ? opts.samples : -1;

    while (samples == -1 || samples-- > 0) {
	if (lines % 15 == 0) {
	    if (opts.context == PM_CONTEXT_ARCHIVE)
		printf("Archive: %s, ", opts.archives[0]);
	    printf("Host: %s, %d cpu(s), %s",
		    host, ncpu,
		    pmCtime((const time_t *)&info.timestamp.tv_sec, timebuf));
/* - report format
  CPU  Busy    Busy  Free Mem   Disk     Load Average
 Util   CPU    Util  (Mbytes)   IOPS    1 Min  15 Min
X.XXX   XXX   X.XXX XXXXX.XXX XXXXXX  XXXX.XX XXXX.XX
*/
	    printf("  CPU");
	    if (ncpu > 1)
		printf("  Busy    Busy");
	    printf("  Free Mem   Disk     Load Average\n");
	    printf(" Util");
	    if (ncpu > 1)
		printf("   CPU    Util");
	    printf("  (Mbytes)   IOPS    1 Min  15 Min\n");
	}
	if (opts.context != PM_CONTEXT_ARCHIVE || pauseFlag)
	    __pmtimevalSleep(opts.interval);
	get_sample(&info);
	printf("%5.2f", info.cpu_util);
	if (ncpu > 1)
	    printf("   %3d   %5.2f", info.peak_cpu, info.peak_cpu_util);
	printf(" %9.3f", info.freemem);
	printf(" %6d", info.dkiops);
	printf("  %7.2f %7.2f\n", info.load1, info.load15);
 	lines++;
    }
    exit(0);
}
Example #4
0
int main(int argc, char **argv) {
	//argument variables
	const char *exe = NULL;
	int perclimit = 0;
	int exe_ok = 0;
	int pid_ok = 0;
	int limit_ok = 0;
	pid_t pid = 0;
	int include_children = 0;

	//get program name
	char *p = (char*)memrchr(argv[0], (unsigned int)'/', strlen(argv[0]));
	program_name = p==NULL ? argv[0] : (p+1);
	//get current pid
	cpulimit_pid = getpid();
	//get cpu count
	NCPU = get_ncpu();

	//parse arguments
	int next_option;
    int option_index = 0;
	//A string listing valid short options letters
	const char* short_options = "+p:e:l:vzih";
	//An array describing valid long options
	const struct option long_options[] = {
		{ "pid",        required_argument, NULL, 'p' },
		{ "exe",        required_argument, NULL, 'e' },
		{ "limit",      required_argument, NULL, 'l' },
		{ "verbose",    no_argument,       NULL, 'v' },
		{ "lazy",       no_argument,       NULL, 'z' },
		{ "include-children", no_argument,  NULL, 'i' },
		{ "help",       no_argument,       NULL, 'h' },
		{ 0,            0,                 0,     0  }
	};

	do {
		next_option = getopt_long(argc, argv, short_options,long_options, &option_index);
		switch(next_option) {
			case 'p':
				pid = atoi(optarg);
				pid_ok = 1;
				break;
			case 'e':
				exe = optarg;
				exe_ok = 1;
				break;
			case 'l':
				perclimit = atoi(optarg);
				limit_ok = 1;
				break;
			case 'v':
				verbose = 1;
				break;
			case 'z':
				lazy = 1;
				break;
			case 'i':
				include_children = 1;
				break;
			case 'h':
				print_usage(stdout, 1);
				break;
			case '?':
				print_usage(stderr, 1);
				break;
			case -1:
				break;
			default:
				abort();
		}
	} while(next_option != -1);

	if (pid_ok && (pid <= 1 || pid >= get_pid_max())) {
		fprintf(stderr,"Error: Invalid value for argument PID\n");
		print_usage(stderr, 1);
		exit(1);
	}
	if (pid != 0) {
		lazy = 1;
	}

	if (!limit_ok) {
		fprintf(stderr,"Error: You must specify a cpu limit percentage\n");
		print_usage(stderr, 1);
		exit(1);
	}
	double limit = perclimit / 100.0;
	if (limit<0 || limit >NCPU) {
		fprintf(stderr,"Error: limit must be in the range 0-%d00\n", NCPU);
		print_usage(stderr, 1);
		exit(1);
	}

	int command_mode = optind < argc;
	if (exe_ok + pid_ok + command_mode == 0) {
		fprintf(stderr,"Error: You must specify one target process, either by name, pid, or command line\n");
		print_usage(stderr, 1);
		exit(1);
	}

	if (exe_ok + pid_ok + command_mode > 1) {
		fprintf(stderr,"Error: You must specify exactly one target process, either by name, pid, or command line\n");
		print_usage(stderr, 1);
		exit(1);
	}

	//all arguments are ok!
	signal(SIGINT, quit);
	signal(SIGTERM, quit);

	//print the number of available cpu
	if (verbose) printf("%d cpu detected\n", NCPU);

	if (command_mode) {
		int i;
		//executable file
		const char *cmd = argv[optind];
		//command line arguments
		char **cmd_args = (char**)malloc((argc-optind + 1) * sizeof(char*));
		if (cmd_args==NULL) exit(2);
		for (i=0; i<argc-optind; i++) {
			cmd_args[i] = argv[i+optind];
		}
		cmd_args[i] = NULL;

		if (verbose) {
			printf("Running command: '%s", cmd);
			for (i=1; i<argc-optind; i++) {
				printf(" %s", cmd_args[i]);
			}
			printf("'\n");
		}

		int child = fork();
		if (child < 0) {
			exit(EXIT_FAILURE);
		}
		else if (child == 0) {
			//target process code
			int ret = execvp(cmd, cmd_args);
			//if we are here there was an error, show it
			perror("Error");
			exit(ret);
		}
		else {
			//parent code
			free(cmd_args);
			int limiter = fork();
			if (limiter < 0) {
				exit(EXIT_FAILURE);
			}
			else if (limiter > 0) {
				//parent
				int status_process;
				int status_limiter;
				waitpid(child, &status_process, 0);
				waitpid(limiter, &status_limiter, 0);
				if (WIFEXITED(status_process)) {
					if (verbose) printf("Process %d terminated with exit status %d\n", child, (int)WEXITSTATUS(status_process));
					exit(WEXITSTATUS(status_process));
				}
				printf("Process %d terminated abnormally\n", child);
				exit(status_process);
			}
			else {
				//limiter code
				if (verbose) printf("Limiting process %d\n",child);
				limit_process(child, limit, include_children);
				exit(0);
			}
		}
	}

	while(1) {
		//look for the target process..or wait for it
		pid_t ret = 0;
		if (pid_ok) {
			//search by pid
			ret = find_process_by_pid(pid);
			if (ret == 0) {
				printf("No process found\n");
			}
			else if (ret < 0) {
				printf("Process found but you aren't allowed to control it\n");
			}
		}
		else {
			//search by file or path name
			ret = find_process_by_name(exe);
			if (ret == 0) {
				printf("No process found\n");
			}
			else if (ret < 0) {
				printf("Process found but you aren't allowed to control it\n");
			}
			else {
				pid = ret;
			}
		}
		if (ret > 0) {
			if (ret == cpulimit_pid) {
				printf("Target process %d is cpulimit itself! Aborting because it makes no sense\n", ret);
				exit(1);
			}
			printf("Process %d found\n", pid);
			//control
			limit_process(pid, limit, include_children);
		}
		if (lazy) break;
		sleep(2);
	};

	exit(0);
}
Example #5
0
int main() {
	int i, ncpu;
	int *child_pid;
	pthread_t tid, tid_runner;
	void *tmpresult;
	long result;
	pthread_attr_t attr;
        struct sched_param param;
        int thread_cpu;

	ncpu = get_ncpu();
	if (ncpu == -1) {
		printf("Can not get the number of CPUs of your machines.\n");
		return PTS_UNRESOLVED;
	}

	printf("System has %d processors\n", ncpu);

        param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1;
        if (sched_setscheduler(getpid(), SCHED_FIFO, &param) != 0) {
		if (errno == EPERM) {
			printf("This process does not have the permission to set its own scheduling policy.\nTry to launch this test as root.\n");
			return PTS_UNRESOLVED;
		}
		perror("An error occurs when calling sched_setscheduler()");
                return PTS_UNRESOLVED;
        }

	child_pid = malloc((ncpu-1)*sizeof(int));

	for (i=0; i<ncpu-1; i++) {
		child_pid[i] = fork();
		if (child_pid[i] == -1) {
			perror("An error occurs when calling fork()");
			return PTS_UNRESOLVED;
		} else if (child_pid[i] == 0) {

			busy_process(i);

			printf("This code should not be executed.\n");
			return PTS_UNRESOLVED;
		}
	}

	pthread_attr_init(&attr);
        pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);

        thread_cpu = ncpu -1;
	if (pthread_create(&tid, &attr, busy_thread, &thread_cpu) != 0) {
		perror("An error occurs when calling pthread_create()");
		return PTS_UNRESOLVED;
	}

	if (pthread_create(&tid_runner, &attr, runner, &thread_cpu) != 0) {
		perror("An error occurs when calling pthread_create()");
		return PTS_UNRESOLVED;
	}

	if (pthread_join(tid_runner, &tmpresult) != 0) {
		perror("An error occurs when calling pthread_join()");
		return PTS_UNRESOLVED;
	}

        for (i=0; i<ncpu-1; i++)
                waitpid(child_pid[i], NULL, 0);

        result = (long)tmpresult;
	if (result) {
		printf("A thread does not relinquish the processor.\n");
		return PTS_FAIL;
	}

	printf("Test PASSED\n");
	return PTS_PASS;

}
Example #6
0
File: 2-2.c Project: jiezh/h5vcc
int main(){
        int child_count, i;
	struct sched_param param;
	int *child_pid;
	float ratio = 0.0;

	nb_child = get_ncpu();
	if(nb_child == -1) {
		printf("Can not get the number of CPUs of your machine.\n");
		return PTS_UNRESOLVED;
	}
	child_pid = malloc(nb_child);

	param.sched_priority = ( sched_get_priority_min(SCHED_RR) +
				 sched_get_priority_max(SCHED_RR) ) / 2;
	
	if(sched_setscheduler(getpid(), SCHED_RR, &param) == -1){
		if(errno == EPERM){
			printf("This process does not have the permission to set its own scheduling policy.\nTry to launch this test as root\n");
		} else {
			perror("An error occurs when calling sched_setscheduler()");
		}
		return PTS_UNRESOLVED;
	}

	if(signal(SIGTERM, sigterm_handler) == SIG_ERR){
		perror("An error occurs when calling signal()");
		return PTS_UNRESOLVED;
        }

	pipe(the_pipe);

	for(i=0; i<nb_child; i++) {
		child_pid[i] = fork();
		if(child_pid[i] == -1){
			perror("An error occurs when calling fork()");
			return PTS_UNRESOLVED;
		} else if (child_pid[i] == 0){
			child_process(i);
			
			printf("This code should not be executed.\n");
			return PTS_UNRESOLVED;
		}
	}

	param.sched_priority = sched_get_priority_max(SCHED_RR);
	if(sched_setparam(0, &param) != 0) {
		perror("An error occurs when calling sched_setparam()");
		return PTS_UNRESOLVED;
	}

	close(STDIN);
	close(the_pipe[1]);
	dup2(the_pipe[0],STDIN);
	close(the_pipe[0]);

	for(i=0; i<NB_LOOP; i++){
		count++;
	}

	if(kill(child_pid[nb_child-1], SIGTERM) != 0) {
		perror("An error occurs when calling kill()");
		return PTS_UNRESOLVED;
	}

	param.sched_priority = sched_get_priority_min(SCHED_RR);
	if(sched_setparam(0, &param) != 0) {
		perror("An error occurs when calling sched_setparam()");
		return PTS_UNRESOLVED;
	}

	while(scanf("*%i*",&child_count) == 0) 
		sched_yield();

	for(i=0; i<nb_child-1; i++) {
		if(kill(child_pid[i], SIGKILL) != 0) {
			perror("An error occurs when calling kill()");
			return PTS_UNRESOLVED;
		}
	}

	if(child_count)
		ratio = (float)count / (float)child_count;

	if(child_count == 0 || ratio >= ACCEPTABLE_RATIO) {
		printf("Test PASSED\n");
		return PTS_PASS;
	} else if(ratio <= (1/ACCEPTABLE_RATIO)) {
		printf("Higher numerical values for the priority represent the lower priorities.\n");
		return PTS_FAIL;
	} else {
		printf("The difference between the processes is not representative.\n");
		return PTS_UNRESOLVED;
	}

}
Example #7
0
T_DECL(thread_request_32848402, "repro for rdar://32848402")
{
	dispatch_queue_attr_t bg_attr, in_attr;

	bg_attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
			QOS_CLASS_BACKGROUND, 0);
	in_attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
			QOS_CLASS_USER_INITIATED, 0);

	dispatch_queue_t a = dispatch_queue_create_with_target("in", in_attr, NULL);
	dispatch_queue_t b = dispatch_queue_create_with_target("bg", bg_attr, NULL);

	end_spin = clock_gettime_nsec_np(CLOCK_MONOTONIC) + 2 * NSEC_PER_SEC;

	dispatch_async_f(a, (void *)0, spin_and_pause);
	long n_threads = MIN((long)get_ncpu(),
			pthread_qos_max_parallelism(QOS_CLASS_BACKGROUND, 0));
	for (long i = 1; i < n_threads; i++) {
		dispatch_async_f(b, (void *)i, spin);
	}

	dispatch_async(b, ^{
		T_PASS("The NCPU+1-nth block got scheduled");
		T_END;
	});

	sleep(10);
	T_FAIL("The NCPU+1-nth block didn't get scheduled");
}
Example #8
0
int main(void)
{
	int *child_pid, oldcount, newcount, shm_id, i, j;
	struct sched_param param;
	key_t key;

	nb_cpu = get_ncpu();

	if (nb_cpu == -1) {
		printf("Can not get the number of CPUs of your machines.\n");
		return PTS_UNRESOLVED;
	}

	child_pid = malloc(nb_cpu * sizeof(int));

	key = ftok("conformance/interfaces/sched_setparam/9-1.c",1234);
	shm_id = shmget(key, sizeof(int), IPC_CREAT|0600);
	if (shm_id < 0) {
		perror("An error occurs when calling shmget()");
		return PTS_UNRESOLVED;
	}

	shmptr = shmat(shm_id, 0, 0);
	if (shmptr == (void*)-1) {
		perror("An error occurs when calling shmat()");
		return PTS_UNRESOLVED;
	}
	*shmptr = 0;

	param.sched_priority = sched_get_priority_min(SCHED_FIFO);
	if (sched_setscheduler(getpid(), SCHED_FIFO, &param) != 0) {
		if (errno == EPERM) {
			printf("This process does not have the permission to set its own scheduling "
			       "parameter.\nTry to launch this test as root\n");
		} else {
			perror("An error occurs when calling sched_setscheduler()");
		}
		return PTS_UNRESOLVED;
	}

	for (i = 0; i < (nb_cpu - 1); i++) {
		child_pid[i] = fork();
		if (child_pid[i] == -1) {
			perror("An error occurs when calling fork()");
			for (j = 0; j < i; j++) {
				kill(child_pid[j], SIGTERM);
			}
			return PTS_UNRESOLVED;
		} else if (child_pid[i] == 0) {

			child_process();

			printf("This code should not be executed.\n");
			return PTS_UNRESOLVED;
		}
	}

	child_pid[i] = fork();
	if (child_pid[i] == -1) {
		perror("An error occurs when calling fork()");
		for (j = 0; j < i; j++) {
			kill(child_pid[j], SIGTERM);
		}
		return PTS_UNRESOLVED;
	} else if (child_pid[i] == 0) {

		test_process();

		printf("This code should not be executed.\n");
		return PTS_UNRESOLVED;
	}

	sleep(1);

	param.sched_priority = (sched_get_priority_min(SCHED_FIFO) +
				sched_get_priority_max(SCHED_FIFO)) / 2;

	oldcount = *shmptr;
	if (sched_setparam(child_pid[i], &param) != 0) {
		perror("An error occurs when calling sched_setparam()");
		kill_children(child_pid);
		return PTS_UNRESOLVED;
	}
	newcount = *shmptr;

	if (newcount == oldcount) {
		printf("The target process does not preempt the calling process\n");
		kill_children(child_pid);
		return PTS_FAIL;
	}

	printf("Test PASSED\n");
	kill_children(child_pid);
	return PTS_PASS;
}
Example #9
0
int main() {
        int child_count, i;
	struct sched_param param;
	int *child_pid;
	float ratio;

	/* Only use a single CPU and one child process
	when set_affinity is availaible.It's because
	no matter what value of the counter is set to,
	There is no guarantee that the LOOP of the child
	can be certainly big enough on any device at any time.
	*/
	int rc = set_affinity(0);
	if (rc) {
		nb_child = get_ncpu();
		if (nb_child == -1) {
			printf("Can not get the number of"
				"CPUs of your machine.\n");
			return PTS_UNRESOLVED;
		}
	} else {
		nb_child = 1;
	}

	child_pid = malloc(nb_child * sizeof(int));
	if (child_pid == NULL) {
		printf("malloc failed\n");
		return PTS_UNRESOLVED;
	}
	param.sched_priority = (sched_get_priority_min(SCHED_RR) +
				 sched_get_priority_max(SCHED_RR)) / 2;

	if (sched_setscheduler(getpid(), SCHED_RR, &param) == -1) {
		if (errno == EPERM) {
			printf("This process does not have the permission to set its own scheduling policy.\nTry to launch this test as root\n");
		} else {
			perror("An error occurs when calling sched_setscheduler()");
		}
		return PTS_UNRESOLVED;
	}

	if (signal(SIGTERM, sigterm_handler) == SIG_ERR) {
		perror("An error occurs when calling signal()");
		return PTS_UNRESOLVED;
        }

	pipe(the_pipe);

	for (i=0; i<nb_child; i++) {
		child_pid[i] = fork();
		if (child_pid[i] == -1) {
			perror("An error occurs when calling fork()");
			return PTS_UNRESOLVED;
		} else if (child_pid[i] == 0) {
			child_process(i);

			printf("This code should not be executed.\n");
			return PTS_UNRESOLVED;
		}
	}

	param.sched_priority = sched_get_priority_max(SCHED_RR);
	if (sched_setparam(0, &param) != 0) {
		perror("An error occurs when calling sched_setparam()");
		return PTS_UNRESOLVED;
	}

	close(STDIN);
	close(the_pipe[1]);
	dup2(the_pipe[0],STDIN);
	close(the_pipe[0]);

	for (i=0; i<NB_LOOP; i++) {
		count++;
	}

	if (kill(child_pid[nb_child-1], SIGTERM) != 0) {
		perror("An error occurs when calling kill()");
		return PTS_UNRESOLVED;
	}

	param.sched_priority = sched_get_priority_min(SCHED_RR);
	if (sched_setparam(0, &param) != 0) {
		perror("An error occurs when calling sched_setparam()");
		return PTS_UNRESOLVED;
	}

	while (scanf("*%i*",&child_count) == 0)
		sched_yield();

	for (i = 0; i < (nb_child-1); i++) {
		if (kill(child_pid[i], SIGKILL) != 0) {
			perror("An error occurs when calling kill()");
			return PTS_UNRESOLVED;
		}
	}

	if (child_count)
		ratio = (float)count / (float)child_count;

	if (child_count == 0 || ratio >= ACCEPTABLE_RATIO) {
		printf("Test PASSED\n");
		return PTS_PASS;
	} else if (ratio <= (1/ACCEPTABLE_RATIO)) {
		printf("Higher numerical values for the priority represent the lower priorities.\n");
		return PTS_FAIL;
	} else {
		printf("The difference between the processes is not representative.\n");
		return PTS_UNRESOLVED;
	}

}
Example #10
0
int main(int argc, char **argv) {

	//get program name
	// char *p=(char*)memrchr(argv[0],(unsigned int)'/',strlen(argv[0]));
	// program_name = p==NULL?argv[0]:(p+1);
        program_name = argv[0];
        int run_in_background = FALSE;
	//parse arguments
	int next_option;
	/* A string listing valid short options letters. */
	const char* short_options="p:e:P:l:c:bqkrvzh";
	/* An array describing valid long options. */
	const struct option long_options[] = {
		{ "pid", required_argument, NULL, 'p' },
		{ "exe", required_argument, NULL, 'e' },
		{ "path", required_argument, NULL, 'P' },
		{ "limit", required_argument, NULL, 'l' },
                { "background", no_argument, NULL, 'b' },
        { "quiet", no_argument, NULL, 'q' },
		{ "verbose", no_argument, NULL, 'v' },
		{ "lazy", no_argument, NULL, 'z' },
		{ "help", no_argument, NULL, 'h' },
                { "cpu", required_argument, NULL, 'c'},
		{ NULL, 0, NULL, 0 }
	};
	//argument variables
	const char *exe=NULL;
	const char *path=NULL;
	int perclimit=0;
	int pid_ok = FALSE;
	int process_ok = FALSE;
	int limit_ok = FALSE;
        int last_known_argument = 0;
        int kill_process = FALSE;   // kill process instead of stopping it
        int restore_process = FALSE;  // restore killed process
        // struct rlimit maxlimit;

        NCPU = get_ncpu();

        opterr = 0;      // avoid unwanted error messages for unknown parameters
	do {
		next_option = getopt_long (argc, argv, short_options,long_options, NULL);
		switch(next_option) {
                        case 'b':
                                run_in_background = TRUE;
                                last_known_argument++;
                                break;
			case 'p':
				pid=atoi(optarg);
                                if (pid)   // valid PID
                                {
				  pid_ok = TRUE;
                                  lazy = TRUE;
                                }
                                last_known_argument += 2;
				break;
			case 'e':
				exe=optarg;
				process_ok = TRUE;
                                last_known_argument += 2;
				break;
			case 'P':
				path=optarg;
				process_ok = TRUE;
                                last_known_argument += 2;
				break;
			case 'l':
				perclimit=atoi(optarg);
				limit_ok = TRUE;
                                last_known_argument += 2;
				break;
                        case 'c':
                                NCPU = atoi(optarg);
                                last_known_argument += 2;
                                break;
                        case 'k':
                                kill_process = TRUE;
                                last_known_argument++;
                                break;
                        case 'r':
                                restore_process = TRUE;
                                last_known_argument++;
                                break;

			case 'v':
				verbose = TRUE;
                                last_known_argument++;
				break;
            case 'q':
                quiet = TRUE;
                                last_known_argument++;
                break;
			case 'z':
				lazy = TRUE;
                                last_known_argument++;
				break;
			case 'h':
				print_usage (stdout, 1);
                                last_known_argument++;
				break;
                        case 'o':
                                last_known_argument++;
                                next_option = -1;
                                break;
			case '?':
				print_usage (stderr, 1);
                                last_known_argument++;
				break;
			case -1:
				break;
			// default:
			//	abort();
		}
	} while(next_option != -1);


        // try to launch a program passed on the command line
        // But only if we do not already have a PID to watch
        if ( (last_known_argument + 1 < argc) && (pid_ok == FALSE) )
        {
           last_known_argument++;
           // if we stopped on "--" jump to the next parameter
           if ( (last_known_argument + 1 < argc) && (! strcmp(argv[last_known_argument], "--") ) )
               last_known_argument++;
           pid_t forked_pid;
           // try to launch remaining arguments
           if (verbose)
           {
               int index = last_known_argument;
               printf("Launching %s", argv[index]);
               for (index = last_known_argument + 1; index < argc; index++)
                    printf(" %s", argv[index]);
               printf(" with limit %d\n", perclimit);
           }
           forked_pid = fork();
           if (forked_pid == -1)  // error
           {
               printf("Failed to launch specified process.\n");
               exit(1);
           }
           else if (forked_pid == 0)   // target child
           {
              execvp(argv[last_known_argument],
                     &(argv[last_known_argument]) );
              exit(2);
           }
           else     // parent who will now fork the throttler
           {
              pid_t limit_pid;
              // if we are planning to kill a process, give it
              // a running head start to avoid death at start-up
              if (kill_process)
                 sleep(5);
     
              limit_pid = fork();
              if (limit_pid == 0)   // child
              {
                 pid = forked_pid;    // the first child
                 lazy = TRUE;
                 pid_ok = TRUE;
                 if (verbose)
                   printf("Throttling process %d\n", (int) pid);
              }
              else    // parent
                exit(0);
           }

           /*
           else if (forked_pid == 0)   // child
           {
               lazy = TRUE;
               pid_ok = TRUE;
               pid = getppid();
               if (verbose)
                  printf("Throttling process %d\n", (int) pid);
           }
           else // parent
           {
               execvp(argv[last_known_argument], 
                      &(argv[last_known_argument]));
               
               // we should never return  
               exit(2);
           }
           */
           
        }      // end of launching child process

	if (!process_ok && !pid_ok) {
		fprintf(stderr,"Error: You must specify a target process\n");
		print_usage (stderr, 1);
		exit(1);
	}
	if ((exe!=NULL && path!=NULL) || (pid_ok && (exe!=NULL || path!=NULL))) {
		fprintf(stderr,"Error: You must specify exactly one target process\n");
		print_usage (stderr, 1);
		exit(1);
	}
	if (!limit_ok) {
		fprintf(stderr,"Error: You must specify a cpu limit\n");
		print_usage (stderr, 1);
		exit(1);
	}
	float limit=perclimit/100.0;
	if ( (limit <= 0.00) || (limit > NCPU) )
        {
		fprintf(stderr,"Error: limit must be in the range of 1 to %d00\n", NCPU);
		print_usage (stderr, 1);
		exit(1);
	}

        // check to see if we should fork
        if (run_in_background)
        {
             pid_t process_id;
             process_id = fork();
             if (! process_id)
                exit(0);
             else
             {
                setsid();
                process_id = fork();
                if (process_id)
                  exit(0);
             }
        }

	//parameters are all ok!
	signal(SIGINT,quit);
	signal(SIGTERM,quit);

        my_pid = getpid();
        if (verbose)
           printf("%d CPUs detected.\n", NCPU);

        increase_priority();
/*
Instead of all this big block of code to detect and change
priority settings, let us just use the increase_priority()
function. It is a little more simple and takes a more
gradual approach, rather than "all or nothing".
-- Jesse

	if (setpriority(PRIO_PROCESS, my_pid,-20)!=0) {
	//if that failed, check if we have a limit 
        // by how much we can raise the priority
#ifdef RLIMIT_NICE 
//check if non-root can even make changes 
// (ifdef because it's only available in linux >= 2.6.13)
		nice_lim=getpriority(PRIO_PROCESS, my_pid);
		getrlimit(RLIMIT_NICE, &maxlimit);

//if we can do better then current
		if( (20 - (signed)maxlimit.rlim_cur) < nice_lim &&  
		    setpriority(PRIO_PROCESS, my_pid,
                    20 - (signed)maxlimit.rlim_cur)==0 //and it actually works
		  ) {

			//if we can do better, but not by much, warn about it
			if( (nice_lim - (20 - (signed)maxlimit.rlim_cur)) < 9) 
                        {
			printf("Warning, can only increase priority by %d.\n",                                nice_lim - (20 - (signed)maxlimit.rlim_cur));
			}
                        //our new limit
			nice_lim = 20 - (signed)maxlimit.rlim_cur; 

		} else 
// otherwise don't try to change priority. 
// The below will also run if it's not possible 
// for non-root to change priority
#endif
		{
			printf("Warning: cannot renice.\nTo work better you should run this program as root, or adjust RLIMIT_NICE.\nFor example in /etc/security/limits.conf add a line with: * - nice -10\n\n");
			nice_lim=INT_MAX;
		}
	} else {
		nice_lim=-20;
	}
*/


	//time quantum in microseconds. it's splitted in a working period and a sleeping one
	int period=100000;
	struct timespec twork,tsleep;   //working and sleeping intervals
	memset(&twork,0,sizeof(struct timespec));
	memset(&tsleep,0,sizeof(struct timespec));

wait_for_process:

	//look for the target process..or wait for it
	if (exe != NULL)
		pid=getpidof(exe);
	else if (path != NULL)
		pid=getpidof(path);
	else 
		waitforpid(pid);

	
	//process detected...let's play

	//init compute_cpu_usage internal stuff
	compute_cpu_usage(0,0,NULL);
	//main loop counter
	int i=0;

	struct timespec startwork,endwork;
	long workingtime=0;		//last working time in microseconds

	if (verbose) print_caption();

	float pcpu_avg=0;

	//here we should already have high priority, for time precision
	while(1) {

		//estimate how much the controlled process is using the cpu in its working interval
		struct cpu_usage cu;
		if (compute_cpu_usage(pid,workingtime,&cu)==-1) {
            if (!quiet)
    			fprintf(stderr,"Process %d dead!\n",pid);
			if (lazy) exit(2);
			//wait until our process appears
			goto wait_for_process;		
		}

		//cpu actual usage of process (range 0-1)
		float pcpu=cu.pcpu;
		//rate at which we are keeping active the process (range 0-1)
		float workingrate=cu.workingrate;

		//adjust work and sleep time slices
		if (pcpu>0) {
			twork.tv_nsec=min(period*limit*1000/pcpu*workingrate,period*1000);
		}
		else if (pcpu==0) {
			twork.tv_nsec=period*1000;
		}
		else if (pcpu==-1) {
			//not yet a valid idea of cpu usage
			pcpu=limit;
			workingrate=limit;
			twork.tv_nsec=min(period*limit*1000,period*1000);
		}
		tsleep.tv_nsec=period*1000-twork.tv_nsec;

		//update average usage
		pcpu_avg=(pcpu_avg*i+pcpu)/(i+1);

		if (verbose && i%10==0 && i>0) {
			printf("%0.2f%%\t%6ld us\t%6ld us\t%0.2f%%\n",pcpu*100,twork.tv_nsec/1000,tsleep.tv_nsec/1000,workingrate*100);
                        if (i%200 == 0)
                           print_caption();
		}

		// if (limit<1 && limit>0) {
                // printf("Comparing %f to %f\n", pcpu, limit);
                if (pcpu < limit)
                {
                        // printf("Continue\n");
			//resume process
			if (kill(pid,SIGCONT)!=0) {
                if (!quiet)
    				fprintf(stderr,"Process %d dead!\n",pid);
				if (lazy) exit(2);
				//wait until our process appears
				goto wait_for_process;
			}
		}

                #ifdef __APPLE_
                // OS X does not have clock_gettime, use clock_get_time
                clock_serv_t cclock;
                mach_timespec_t mts;
                host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
                clock_get_time(cclock, &mts);
                mach_port_deallocate(mach_task_self(), cclock);
                startwork.tv_sec = mts.tv_sec;
                startwork.tv_nsec = mts.tv_nsec;

                #else
		clock_gettime(CLOCK_REALTIME,&startwork);
                #endif

		nanosleep(&twork,NULL);		//now process is working
                #ifdef __APPLE__
                // OS X does not have clock_gettime, use clock_get_time
                // clock_serv_t cclock;
                // mach_timespec_t mts;
                host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
                clock_get_time(cclock, &mts);
                mach_port_deallocate(mach_task_self(), cclock);
                endwork.tv_sec = mts.tv_sec;
                endwork.tv_nsec = mts.tv_nsec;

                #else
		clock_gettime(CLOCK_REALTIME,&endwork);
                #endif
		workingtime=timediff(&endwork,&startwork);

		// if (limit<1) {
                // printf("Checking %f vs %f\n", pcpu, limit);
                if (pcpu > limit)
                {
                     // When over our limit we may run into
                     // situations where we want to kill
                     // the offending process, then restart it
                     if (kill_process)
                     {
                         kill(pid, SIGKILL);
                         if (!quiet)
                             fprintf(stderr, "Process %d killed.\n", pid);
                         if ( (lazy) && (! restore_process) ) 
                              exit(2);
                         // restart killed process
                         if (restore_process)
                         {
                             pid_t new_process;
                             new_process = fork();
                             if (new_process == -1)
                             {
                              fprintf(stderr, "Failed to restore killed process.\n");
                             }
                             else if (new_process == 0)
                             {
                                // child which becomes new process
                                if (verbose)
                                   printf("Relaunching %s\n",
                                          argv[last_known_argument]);
                                execvp(argv[last_known_argument],
                                       &(argv[last_known_argument]) ); 
                             }
                             else // parent
                             {
                                // we need to track new process
                                pid = new_process;
                                // avoid killing child process
                                sleep(5);
                             }
                         }
                     }
                     // do not kll process, just throttle it
                     else
                     {

                        // printf("Stop\n");
			//stop process, it has worked enough
			if (kill(pid,SIGSTOP)!=0) {
                if (!quiet)
    				fprintf(stderr,"Process %d dead!\n", pid);
				if (lazy) exit(2);
				//wait until our process appears
				goto wait_for_process;
			}
			nanosleep(&tsleep,NULL);	//now process is sleeping
                      }   // end of throttle process
		}         // end of process using too much CPU
		i++;
	}

   return 0;
}