<commit_before>package com.example.odroiddvfs;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import android.util.Log;

public class DVFS {

	public static final String TAG = "DVFS";

	private IOStuff io;
	private CPUStuff cpu;
	private GPUStuff gpu;

	private ScheduledExecutorService scheduler;
	public static final float TIME_INTERVAL_NANO_SECONDS = 1000000000;

	private int fpsLowBound;
	private int fpsHighBound;
	private int slidingWindowLength;

	private int currentSlidingWindowPosition;

	public DVFS(){
		io = new IOStuff();
		io.startShell();
		cpu = new CPUStuff(io);
		gpu = new GPUStuff(io);
		io.stopShell();
	}


	public void start(int fpsLowbound, int fpsHighBound, int slidingWindowLength){
		this.fpsLowBound = fpsLowbound;
		this.fpsHighBound = fpsHighBound;
		this.slidingWindowLength = slidingWindowLength;
		currentSlidingWindowPosition = 0;

		io.startShell();


		scheduler = Executors.newSingleThreadScheduledExecutor();

		scheduler.scheduleAtFixedRate
		(new Runnable() {
			public void run() {
				float gpuUtil = gpu.getGPUUtilisation();

				float cpuUtil = cpu.getCPUUtilisation();

				int fps = gpu.getFPS(TIME_INTERVAL_NANO_SECONDS);


				Log.i(TAG, "FPS: " + Integer.toString(fps) + ", GPU: " + Float.toString(gpuUtil) + ", CPU: " + Float.toString(cpuUtil));

				processInputs(fps, gpuUtil, cpuUtil);

			}
		}, 0, 1000, TimeUnit.MILLISECONDS);
	}

	public void stop(){
		io.stopShell();


		if(scheduler != null){
			scheduler.shutdownNow();
			scheduler = null;

		}
	}


	private void processInputs(int fps, float gpuUtil, float cpuUtil){

		if(fps == GPUStuff.NO_FPS_CALCULATED){
			return;
		}

		int newFPSValue = 0;

		if(fps > fpsHighBound){
			//We need to decrease FPS
			newFPSValue = fpsLowBound;
		} else if(fps < fpsLowBound){
			//We need to increase FPS
			newFPSValue = fpsHighBound;
		} else {
			currentSlidingWindowPosition = 0;
			return;
		}


		currentSlidingWindowPosition++;

		if(currentSlidingWindowPosition > slidingWindowLength){
			currentSlidingWindowPosition = 0;
			makeGPUMeetThisFPS(newFPSValue, fps, gpuUtil);
		}

		makeCPUMeetThisFPS(newFPSValue, fps, cpuUtil);

	}


	private void makeCPUMeetThisFPS(int Q_targetFPS, int Q_currentFPS, double UC_cpuUtil){
		Log.i(TAG, "CPU meet this FPS: " + Q_targetFPS);

		long c_currentCPUFreq = cpu.getCurrentCPUFrequency();	

		double PC_priceCPU = (UC_cpuUtil * c_currentCPUFreq) / Q_currentFPS;
		double OC_expectedCPUCost = PC_priceCPU * Q_targetFPS;


		int newCPUFreqPosition = findLowestFreqPositionThatMeetsThisCost(OC_expectedCPUCost, cpu.getCPUFreqs(), UC_cpuUtil);
		int currentCPUFreqPosition = cpu.getCpuFreqPosition();		<commit_msg>don't get CPU or GPU utilisation if they are not needed<commit_after>package com.example.odroiddvfs;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import android.util.Log;

public class DVFS {

	public static final String TAG = "DVFS";

	private IOStuff io;
	private CPUStuff cpu;
	private GPUStuff gpu;

	private ScheduledExecutorService scheduler;
	public static final float TIME_INTERVAL_NANO_SECONDS = 1000000000;
	public static final int DO_NOT_PURSUE_FPS_VALUE = -1;

	private int fpsLowBound;
	private int fpsHighBound;
	private int slidingWindowLength;

	private int currentSlidingWindowPosition;

	public DVFS(){
		io = new IOStuff();
		io.startShell();
		cpu = new CPUStuff(io);
		gpu = new GPUStuff(io);
		io.stopShell();
	}


	public void start(int fpsLowbound, int fpsHighBound, int slidingWindowLength){
		this.fpsLowBound = fpsLowbound;
		this.fpsHighBound = fpsHighBound;
		this.slidingWindowLength = slidingWindowLength;
		currentSlidingWindowPosition = 0;

		io.startShell();


		scheduler = Executors.newSingleThreadScheduledExecutor();

		scheduler.scheduleAtFixedRate
		(new Runnable() {
			public void run() {
				int currentFPS = gpu.getFPS(TIME_INTERVAL_NANO_SECONDS);
				
				int newValueFPS = shouldPursueFPSRecalculationToThisFPS(currentFPS);
				Log.i(TAG, "FPS: " + Integer.toString(currentFPS));
				
				if(newValueFPS != DO_NOT_PURSUE_FPS_VALUE){
					processInputs(currentFPS, newValueFPS);
				}





			}
		}, 0, 1000, TimeUnit.MILLISECONDS);
	}

	public void stop(){
		io.stopShell();


		if(scheduler != null){
			scheduler.shutdownNow();
			scheduler = null;

		}
	}
	
	private int shouldPursueFPSRecalculationToThisFPS(int fps){
		if(fps == GPUStuff.NO_FPS_CALCULATED){
			return DO_NOT_PURSUE_FPS_VALUE;
		}

		if(fps > fpsHighBound){
			//We need to decrease FPS
			return fpsLowBound;
		} else if(fps < fpsLowBound){
			//We need to increase FPS
			return fpsHighBound;
		} else {
			currentSlidingWindowPosition = 0;
			return DO_NOT_PURSUE_FPS_VALUE;
		}

	}


	private void processInputs(int currentFPS, int newFPSValue){
		
		Log.i(TAG, "Current FPS: " + Integer.toString(currentFPS) + ", target FPS " + Integer.toString(newFPSValue));

		currentSlidingWindowPosition++;

		if(currentSlidingWindowPosition > slidingWindowLength){
			
			currentSlidingWindowPosition = 0;
			
			float gpuUtil = gpu.getGPUUtilisation();
			Log.i(TAG, "GPU Util: " + gpuUtil);
			
			makeGPUMeetThisFPS(newFPSValue, currentFPS, gpuUtil);
		}
		
		float cpuUtil = cpu.getCPUUtilisation();
		
		Log.i(TAG, "CPU Util: " + cpuUtil);
	

		makeCPUMeetThisFPS(newFPSValue, currentFPS, cpuUtil);

	}


	private void makeCPUMeetThisFPS(int Q_targetFPS, int Q_currentFPS, double UC_cpuUtil){
		Log.i(TAG, "CPU meet this FPS: " + Q_targetFPS);

		long c_currentCPUFreq = cpu.getCurrentCPUFrequency();	

		double PC_priceCPU = (UC_cpuUtil * c_currentCPUFreq) / Q_currentFPS;
		double OC_expectedCPUCost = PC_priceCPU * Q_targetFPS;


		int newCPUFreqPosition = findLowestFreqPositionThatMeetsThisCost(OC_expectedCPUCost, cpu.getCPUFreqs(), UC_cpuUtil);
		int currentCPUFreqPosition = cpu.getCpuFreqPosition();		
{'fraction_non_alphanumeric': 0.09694733310969474, 'fraction_numerical': 0.00637370010063737, 'mean_word_length': 4.567693744164332, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2267030', 'n_tokens_mistral': 2382, 'n_tokens_neox': 2067, 'n_words': 432}