Beispiel #1
0
int main(int argc, char **argv)
{
	sigset_t mask, oldmask;
	union sched_config *p;
	size_t len;
	int ret;

	mlockall(MCL_CURRENT | MCL_FUTURE);

	/*
	 * For a recurring global time frame of 400 ms, we define a TP
	 * schedule as follows:
	 *
	 * - thread(s) assigned to partition #2 (tag C) shall be
	 * allowed to run for 100 ms, when the next global time frame
	 * begins.
	 *
	 * - thread(s) assigned to partition #1 (tag B) shall be
	 * allowed to run for 50 ms, after the previous time slot
	 * ends.
	 *
	 * - thread(s) assigned to partition #0 (tag A) shall be
	 * allowed to run for 20 ms, after the previous time slot
	 * ends.
	 *
	 * - when the previous time slot ends, no TP thread shall be
	 * allowed to run until the global time frame ends (special
	 * setting of ptid == -1), i.e. 230 ms.
	 */
	len = sched_tp_confsz(NR_WINDOWS);
	p = malloc(len);
	if (p == NULL)
		error(1, ENOMEM, "malloc");

	p->tp.nr_windows = NR_WINDOWS;
	p->tp.windows[0].offset.tv_sec = 0;
	p->tp.windows[0].offset.tv_nsec = 0;
	p->tp.windows[0].duration.tv_sec = 0;
	p->tp.windows[0].duration.tv_nsec = 100000000;
	p->tp.windows[0].ptid = 2;
	p->tp.windows[1].offset.tv_sec = 0;
	p->tp.windows[1].offset.tv_nsec = 100000000;
	p->tp.windows[1].duration.tv_sec = 0;
	p->tp.windows[1].duration.tv_nsec = 50000000;
	p->tp.windows[1].ptid = 1;
	p->tp.windows[2].offset.tv_sec = 0;
	p->tp.windows[2].offset.tv_nsec = 150000000;
	p->tp.windows[2].duration.tv_sec = 0;
	p->tp.windows[2].duration.tv_nsec = 20000000;
	p->tp.windows[2].ptid = 0;
	p->tp.windows[3].offset.tv_sec = 0;
	p->tp.windows[3].offset.tv_nsec = 170000000;
	p->tp.windows[3].duration.tv_sec = 0;
	p->tp.windows[3].duration.tv_nsec = 230000000;
	p->tp.windows[3].ptid = -1;

	/* Assign the TP schedule to CPU #0 */
	ret = sched_setconfig_np(0, SCHED_TP, p, len);
	if (ret)
		error(1, ret, "sched_setconfig_np");

	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	signal(SIGINT, cleanup);
	sigaddset(&mask, SIGTERM);
	signal(SIGTERM, cleanup);
	sigaddset(&mask, SIGHUP);
	signal(SIGHUP, cleanup);
	pthread_sigmask(SIG_BLOCK, &mask, &oldmask);

	sem_init(&barrier, 0, 0);
	create_thread(threadA, 0);
	create_thread(threadB, 1);
	create_thread(threadC, 2);
	sem_post(&barrier);

	sigsuspend(&oldmask);

	return 0;
}
Beispiel #2
0
static double run_quota(int quota)
{
	size_t len = sched_quota_confsz();
	unsigned long long count;
	union sched_config cf;
	struct timespec req;
	int ret, tgid, n;
	double percent;
	char label[8];

	cf.quota.op = sched_quota_add;
	cf.quota.add.pshared = 0;
	ret = sched_setconfig_np(0, SCHED_QUOTA, &cf, len);
	if (ret)
		error(1, ret, "sched_setconfig_np(add-quota-group)");

	tgid = cf.quota.info.tgid;
	cf.quota.op = sched_quota_set;
	cf.quota.set.quota = quota;
	cf.quota.set.quota_peak = quota;
	cf.quota.set.tgid = tgid;
	ret = sched_setconfig_np(0, SCHED_QUOTA, &cf, len);
	if (ret)
		error(1, ret, "sched_setconfig_np(set-quota, tgid=%d)", tgid);

	printf("new thread group #%d on CPU0, quota sum is %d%%\n",
	       tgid, cf.quota.info.quota_sum);

	for (n = 0; n < nrthreads; n++) {
		sprintf(label, "t%d", n);
		create_quota_thread(threads[n], label, tgid, counts[n]);
		sem_wait(&ready);
	}

	pthread_mutex_lock(&lock);
	started = 1;
	pthread_cond_broadcast(&barrier);
	pthread_mutex_unlock(&lock);

	req.tv_sec = TEST_SECS;
	req.tv_nsec = 0;
	clock_nanosleep(CLOCK_MONOTONIC, 0, &req, NULL);

	for (n = 0, count = 0; n < nrthreads; n++) {
		count += counts[n];
		pthread_kill(threads[n], SIGDEMT);
	}

	percent = ((double)count / TEST_SECS) * 100.0 / loops_per_sec;

	for (n = 0; n < nrthreads; n++) {
		__real_printf("done quota_thread[%d], count=%lu\n", n, counts[n]);
		pthread_cancel(threads[n]);
		pthread_join(threads[n], NULL);
	}

	cf.quota.op = sched_quota_remove;
	cf.quota.remove.tgid = tgid;
	ret = sched_setconfig_np(0, SCHED_QUOTA, &cf, len);
	if (ret)
		error(1, ret, "sched_setconfig_np(remove-quota-group)");

	return percent;
}