Beispiel #1
0
//this function is an autonomous dynamic system
//it works with static variables (state variables of the system), that keep memory of recent past
//its aim is to estimate the cpu usage of the process
//to work properly it should be called in a fixed periodic way
//perhaps i will put it in a separate thread...
int compute_cpu_usage(int pid, int last_working_quantum,
		      struct cpu_usage *pusage)
{
#define MEM_ORDER 10
    //circular buffer containing last MEM_ORDER process screenshots
    static struct process_screenshot ps[MEM_ORDER];
    //the last screenshot recorded in the buffer
    static int front = -1;
    //the oldest screenshot recorded in the buffer
    static int tail = 0;

    if (pusage == NULL) {
	//reinit static variables
	front = -1;
	tail = 0;
	return 0;
    }
    //let's advance front index and save the screenshot
    front = (front + 1) % MEM_ORDER;
    int j = getjiffies(pid);
    if (j >= 0)
	ps[front].jiffies = j;
    else
	return -1;		//error: pid does not exist
    clock_gettime(CLOCK_REALTIME, &(ps[front].when));
    ps[front].cputime = last_working_quantum;

    //buffer actual size is: (front-tail+MEM_ORDER)%MEM_ORDER+1
    int size = (front - tail + MEM_ORDER) % MEM_ORDER + 1;

    if (size == 1) {
	//not enough samples taken (it's the first one!), return -1
	pusage->pcpu = -1;
	pusage->workingrate = 1;
	return 0;
    } else {
	//now we can calculate cpu usage, interval dt and dtwork are expressed in microseconds
	long dt = timediff(&(ps[front].when), &(ps[tail].when));
	long dtwork = 0;
	int i = (tail + 1) % MEM_ORDER;
	int max = (front + 1) % MEM_ORDER;
	do {
	    dtwork += ps[i].cputime;
	    i = (i + 1) % MEM_ORDER;
	} while (i != max);
	int used = ps[front].jiffies - ps[tail].jiffies;
	float usage = (used * 1000000.0 / HZ) / dtwork;
	pusage->workingrate = 1.0 * dtwork / dt;
	pusage->pcpu = usage * pusage->workingrate;
	if (size == MEM_ORDER)
	    tail = (tail + 1) % MEM_ORDER;
	return 0;
    }
#undef MEM_ORDER
}
Beispiel #2
0
/**
 * Stop a timer
 * @param clock The timer
 * @return TRUE if the timer was stopped or FALSE if the timer was already stopped.
 */
int meas_stop_clock(meas_clock *clock)
{
	if(clock == NULL)
		return(FALSE);

	clock->state    = TIMER_ST_STOPPED;
	clock->end_time = getjiffies();
	clock->interv   = clock->end_time - clock->start_time;

	return(TRUE);
}
Beispiel #3
0
/**
 * Start or/and create a timer
 * @param mst The meas user structure. This argument is necessary only in the first call to create the clock (second argument will be NULL). After that, you can just pass NULL to mst and pass the clock in second argument.
 * @param clock The clock created with this function. Use NULL in the first call.
 * @param name A name to the clock (useful for report visualization).
 * @return NULL if both mst and clock are different of NULL or the created clock.
 */
meas_clock *meas_start_clock(meas_t **mst, meas_clock *clock, char *name)
{
	meas_t *umst = *mst;
	meas_clock *ntimer;

	if(mst != NULL && clock == NULL) {
		if((ntimer = (meas_clock*)malloc(sizeof(meas_clock))) == NULL)
			return(NULL);

		ntimer->interv = 0;
		llist_add(&umst->timers, ntimer);
	} else if(mst == NULL && clock != NULL) {
		ntimer = clock;
	} else {
		return(NULL);
	}

	ntimer->state = TIMER_ST_RUNNING;
	ntimer->start_time = getjiffies();
	strcpy(ntimer->name, name);
	return(ntimer);
}
Beispiel #4
0
//this function is an autonomous dynamic system
//it works with static variables (state variables of the system), that keep memory of recent past
//its aim is to estimate the cpu usage of the process
//to work properly it should be called in a fixed periodic way
//perhaps i will put it in a separate thread...
int compute_cpu_usage(int pid,int last_working_quantum,struct cpu_usage *pusage) {
	#define MEM_ORDER 10
	//circular buffer containing last MEM_ORDER process screenshots
	static struct process_screenshot ps[MEM_ORDER];
	//the last screenshot recorded in the buffer
	static int front=-1;
	//the oldest screenshot recorded in the buffer
	static int tail=0;

	if (pusage==NULL) {
		//reinit static variables
		front=-1;
		tail=0;
		return 0;
	}

	//let's advance front index and save the screenshot
	front=(front+1)%MEM_ORDER;
	int j=getjiffies(pid);
	if (j>=0) ps[front].jiffies=j;
	else return -1;	//error: pid does not exist

        #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);
        ps[front].when.tv_sec = mts.tv_sec;
        ps[front].when.tv_nsec = mts.tv_nsec;

        #else
        // Linux and BSD can use real time
	clock_gettime(CLOCK_REALTIME,&(ps[front].when));
	ps[front].cputime=last_working_quantum;
        #endif
	//buffer actual size is: (front-tail+MEM_ORDER)%MEM_ORDER+1
	int size=(front-tail+MEM_ORDER)%MEM_ORDER+1;

	if (size==1) {
		//not enough samples taken (it's the first one!), return -1
		pusage->pcpu=-1;
		pusage->workingrate=1;
		return 0;
	}
	else {
		//now we can calculate cpu usage, interval dt and dtwork are expressed in microseconds
		long dt=timediff(&(ps[front].when),&(ps[tail].when));
		long dtwork=0;
		int i=(tail+1)%MEM_ORDER;
		int max=(front+1)%MEM_ORDER;
		do {
			dtwork+=ps[i].cputime;
			i=(i+1)%MEM_ORDER;
		} while (i!=max);
		int used=ps[front].jiffies-ps[tail].jiffies;
		float usage=(used*1000000.0/HZ)/dtwork;
		pusage->workingrate=1.0*dtwork/dt;
		pusage->pcpu=usage*pusage->workingrate;
		if (size==MEM_ORDER)
			tail=(tail+1)%MEM_ORDER;
		return 0;
	}
	#undef MEM_ORDER
}