Round-Robin time-slice

Hi everyone!

I’m trying to change the time-slice (quantum) of the Round-Robin schedule with POSIX patterns.

I have already try to use this:

  • sched_rr_get_interval(0, &timeTrigger);
    Where:
  • 0 is the current process;
  • &timeTrigger is a reference to a timespec configured with 2 seconds.

Here’s going the code:

#include "RoundRobin.h"
#include <pthread.h>
#include <sched.h>
#include <cstdlib>
#include <iostream>
#include <sys/time.h>
#include <unistd.h>

#define NUM_PTHREADS		2
#define MICRO_PER_SECOND	1000000

struct timeval now, start, stop;
struct timespec timeTrigger, timeCondition;

int fire=1;

pthread_t myPthreads[NUM_PTHREADS];
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
//pthread_cond_t myCond = PTHREAD_COND_INITIALIZER;
pthread_attr_t myAttr;

using namespace std;

void *Work (void *ptr){
	int i = (int) ptr;

	pthread_mutex_lock(&myMutex);

//	timeCondition.tv_sec = now.tv_sec + fire;

//	pthread_cond_timedwait(&myCond, &myMutex, &timeCondition);

	cout << "\nPrinting PThread" << i << endl;
	for(int j=1;j <= 6; j++){
		cout << j << " ";
		sleep(1);
	}

//	fire += 5;

	pthread_mutex_unlock(&myMutex);

	return NULL;
}

RoundRobin::RoundRobin() {
	// TODO Auto-generated constructor stub

}

RoundRobin::~RoundRobin() {
	// TODO Auto-generated destructor stub
}

void RoundRobin::CriaPThreads(){

	int resultOfCreatePthread=0;

	gettimeofday(&now, NULL);
	timeTrigger.tv_sec = now.tv_sec + 2;

	pthread_cond_init(&myCond, NULL);
	pthread_attr_init(&myAttr);
	pthread_attr_setschedpolicy(&myAttr, SCHED_RR);
//	pthread_attr_setscope(&myAttr, PTHREAD_SCOPE_PROCESS);
	pthread_attr_setinheritsched(&myAttr, PTHREAD_EXPLICIT_SCHED);

	sched_rr_get_interval(getpid(), &timeTrigger);

	for (int i=1; i <= NUM_PTHREADS; i++){
		resultOfCreatePthread = pthread_create(&myPthreads[i], &myAttr,
				Work, (void *)i);
		if (resultOfCreatePthread != 0)
			cout << "PThread " << i << ": Impossible to create." << endl;
	}
}

void RoundRobin::AguardaFinalizacaoPthread(){

	for (int i=1; i <= NUM_PTHREADS; i++)
		pthread_join(myPthreads[i], NULL);

	pthread_attr_destroy(&myAttr);
	pthread_mutex_destroy(&myMutex);
//	pthread_cond_destroy(&myCond);
}

I wanna set some pthreads and when the first pthread reach the timeslice (or quantum) the second pthread take the CPU and the first one go to the end of the queue.

I already now that it’s just like the Round-Robin schedule.
But I need some way to do this with POSIX.

Thanks in advance!

Set the two threads to the same priority and that’s it.

You can change the time-slice period (ClockPeriod()) but that will affect the whole machine.

Thanks for the tip.

But can you tell me more about the problems of using ClockPeriod (about affecting the whole machine)?

I’ve changed my code but nothing happenned:

void RoundRobin::CriaPThreads(){

	int resultOfCreatePthread=0;

	struct _clockperiod clkper;
	clkper.nsec = 2000000000;
	ClockPeriod(clockId, &clkper, NULL, 0);

//	sched_rr_get_interval(getpid(), &timeTrigger);
//	clock_settime(clockId, &timeTrigger);

	pthread_attr_init(&myAttr);
//	pthread_attr_setschedpolicy(&myAttr, SCHED_FIFO);
	pthread_attr_setschedpolicy(&myAttr, SCHED_RR);
//	pthread_attr_setscope(&myAttr, PTHREAD_SCOPE_SYSTEM);
	pthread_attr_setscope(&myAttr, PTHREAD_SCOPE_PROCESS);
	pthread_attr_setinheritsched(&myAttr, PTHREAD_EXPLICIT_SCHED);

	for (int i=1; i <= NUM_PTHREADS; i++){
		pthread_setschedprio(myPthreads[i], 10);
		resultOfCreatePthread = pthread_create(&myPthreads[i], &myAttr,
				Work, (void *)i);
		if (resultOfCreatePthread != 0)
			cout << "PThread " << i << ": Impossible to create." << endl;
	}
}

There is no “problem” with ClockPeriod, it’s that if you changed the time-slice to something smaller then the default, then overhead is added not only to your process but to the whole system. It also affect the precision of all timers in the system. Time-Slice period is 4 types what the timer resolution are. Hence if you set ClockPeriod to 2 secondes like you did, timer resolution becomes 2seconds ( that’s very bad ), and time slice becomes 8 secondes. I don’t think ClockPeriod would allow you to set such a big value.

I don’t know what you expect your program to do though? You want one thread to run 2 seconds and then another thread to run 2 other seconds and so on? This is not a job for the kernel per se. Instead use a thread that will run at higher priority then your work thread. Setup this thread to wakeup every 2 seconds and then have it dynamicaly changing the priority of the work thread. Should be easy to code. Don’t forget to set the work threads schedule policity to FIFO. This will be POSIX and be portable.