Example #1
0
void parseLine(String str) {
	if (str.empty()) { return; }
	if ( parseSetCommand( str ) ) { return; }
	
	std::stringstream ss;
	ss.str(str);
	ss >> str;
	
	if ( (str[0] >= '0') && (str[0] <= '9') ) {	
		int dest = std::stoi(str);
		if ( (dest < 0) || (dest >= indexes) ) { return; }
		for ( int i = currentLine; i < currentLine + noteLength; ++i ) {
			outputFiles[dest] << lines[i] << "\n";
		}
		removeCurrentNote();
		return;
	}
	
	if ( str == "save" ) {
		saveState();
	} else if ( str == "s" ) {
		if (currentLine != (int)lines.size()) {
			log.push_back( String("Skipped ") + std::to_string(currentLine) );
		}
		int before = currentLine;
		getNextNoteLine();
		if ((before != currentLine) && (currentLine == (int)lines.size())) {
			log.push_back("Reached End of Input");
		}
		return;
	}
	if ( str == "i" ) {
		std::cout << "Insert Custom Note > ";
		String line;
		getline(std::cin, line);
		if ( !isBlankLine(line) ) {
			lines.insert( lines.begin() + currentLine, line );
		}
	}
	if ( str == "d" ) {
		log.push_back( String("Deleted ") + std::to_string(currentLine) );
		removeCurrentNote();
	}
	if ( str == "p" ) {
		log.push_back("Previous");
		--currentLine;
		currentLine = std::max(0, currentLine);
	}
	if ( str == "q" ) {
		doQuit = true;
		return;
	}
	if ( str == "\t" ) {
		enterSubNote();
	}
	
	ss.str("");
	ss.clear();
}
int main (int argc,const char **argv) {

	int argvStep;
	unsigned int currentNode;
	unsigned int currentCore;

	Processor *processor;
	PState ps(0);

	bool autoRecall=false;
	int autoRecallTimer=60;
	
	CfgManager *cfgInstance;
	int errorLine;
	
	Scaler *scaler;

	int rv;
	int parsed = 0;
	int parsed_set = 0;

	printf ("TurionPowerControl %s (%s) %s\n", _VERSION, _SOURCE_VERSION, _TARGET_OS);
	printf ("Turion Power States Optimization and Control - by blackshard\n\n");

	if (argc<2) {
		printUsage(argv[0]);

		return 0;
	}

	if (initializeCore() == false) {
		return -1;
	}

	processor=getSupportedProcessor ();
	if (processor==NULL) {
		printf ("No supported processor detected, sorry.\n");
		return -2;
	}
	
	//Initializes currentNode and currentCore
	currentNode=processor->ALL_NODES;
	currentCore=processor->ALL_CORES;

	//Initializes the scaler based on the processor found in the system
	scaler=new Scaler (processor);
	
	for (argvStep = 1; ; argvStep++) {

		if (argvStep == argc) {
			if (!autoRecall)
				break;
			//Autorecall feature set argvStep back to 1 when it reaches end
			printf("Autorecall activated. Timeout: %d seconds\n", autoRecallTimer);
			Sleep(autoRecallTimer * 1000);
			printf("Autorecalling...\n");
			argvStep = 1;
		}

		//Reinitializes the processor object for active node and core in the system
		processor->setNode(currentNode);
		processor->setCore(currentCore);

		//printf ("Parsing argument %d %s\n",argvStep,argv[argvStep]);

		if (parsed_set) {
			printf("ERROR: -set can only be used exclusively\n");
			break;
		}
		parsed++;

		//List power states action
		if (strcmp(argv[argvStep], "-l") == 0) {

			processorStatus (processor);
			continue;
		}

		//Set the current operational node
		if (strcmp(argv[argvStep], "-node") == 0) {

			unsigned int thisNode;
			const char *arg = argv[argvStep + 1];

			if (arg == NULL) {
				printf("-node requires an argument\n");
				break;
			}
			if (strcmp(arg, "all") != 0) {
				if (requireUnsignedInteger(argc, argv, argvStep + 1, &thisNode)) {
					printf("ERROR: invalid -node -- %s\n", arg);
					break;
				}
				if (thisNode >= processor->getProcessorNodes()) {
					printf("ERROR: node must be in 0-%u range\n", processor->getProcessorNodes() - 1);
					break;
				}
				currentNode = thisNode;
			} else {
				currentNode = processor->ALL_NODES;
			}
			argvStep++;
			continue;
		}

		//Set the current operational core
		if (strcmp(argv[argvStep], "-core") == 0) {

			unsigned int thisCore;
			const char *arg = argv[argvStep + 1];

			if (arg == NULL) {
				printf("ERROR: -core requires an argument\n");
				break;
			}
			if (strcmp(arg, "all") != 0) {
				if (requireUnsignedInteger(argc, argv, argvStep + 1, &thisCore)) {
					printf("ERROR: invalid -core -- %s\n", arg);
					break;
				}
				if (thisCore >= processor->getProcessorCores()) {
					printf("ERROR: core must be in 0-%u range\n", processor->getProcessorCores() - 1);
					break;
				}
				currentCore = thisCore;
			} else {
				currentCore = processor->ALL_CORES;
			}
			argvStep++;
			continue;
		}

		rv = parseSingleSetSubcommand(processor, argc, argv, argvStep, 1, &ps);
		if (rv >= 0) {
			printf("\n");
			argvStep = rv - 1;
			continue;
		}
		if (rv == PARSE_WRONG_FORMAT) {
			break;
		}

		if (strcmp(argv[argvStep], "-nbvid") == 0) {
			unsigned int nbvid;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -nbvid requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &nbvid)) { 
				printf("ERROR: invalid NBVid -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (processor->getProcessorIdentifier() == PROCESSOR_10H_FAMILY) {
				processor->setNBVid (ps, nbvid);
				print_stat(processor, ps, "nbvid", nbvid, PRINT_STAT_FLAG_NODE | PRINT_STAT_FLAG_PSTATE);
				if (processor->getNBVid(ps) != nbvid)
					printf(" (actual: %d)", processor->getNBVid(ps));
				printf("\n\n");
			} else {
				processor->setNBVid (nbvid);
				print_stat(processor, ps, "nbvid", nbvid, PRINT_STAT_FLAG_NODE);
				if (processor->getNBVid() != nbvid)
					printf(" (actual: %d)", processor->getNBVid());
				printf("\n\n");
			}
			argvStep = argvStep + 1;
			continue;
		}

		if (strcmp(argv[argvStep], "-nbdid") == 0) {

			if (processor->getProcessorIdentifier() == PROCESSOR_10H_FAMILY) {
				unsigned int nbdid;

				if (argv[argvStep + 1] == NULL) {
					printf("ERROR: -nbdid requires an argument\n");
					break;
				}
				if (requireUnsignedInteger(argc, argv, argvStep + 1, &nbdid)) { 
					printf("ERROR: invalid NBDid -- %s\n", argv[argvStep + 1]);
					break;
				}
				processor->setNBDid (ps, nbdid);
				print_stat(processor, ps, "nbdid", nbdid, PRINT_STAT_FLAG_NODE | PRINT_STAT_FLAG_PSTATE);
				if (processor->getNBDid(ps) != nbdid)
					printf(" (actual: %d)", processor->getNBDid(ps));
				printf("\n\n");
				argvStep = argvStep + 1;
			} else {
				printf("ERROR: -nbdid is only supported on family 10h processors\n");
				break;
			}
			continue;
		}

		if (strcmp(argv[argvStep], "-nbfid") == 0) {

			unsigned int nbfid;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -nbfid requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &nbfid)) { 
				printf("ERROR: invalid NBFid -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setNBFid(nbfid);
			print_stat(processor, ps, "nbfid", nbfid, PRINT_STAT_FLAG_NODE);
			if (processor->getNBFid() != nbfid)
				printf(" (actual: %d)", processor->getNBFid());
			printf("\n\n");
			argvStep += 1;
			continue;
		}

		/*
		 * Following section will set a new frequency for selected pstate/core/node
		 */
		if (strcmp(argv[argvStep], "-nbfreq") == 0 || 
			strcmp(argv[argvStep], "-nbf") == 0 || 
			strcmp(argv[argvStep], "-nbfrequency") == 0) {

			unsigned int nbfrequency;

			if (argv[argvStep + 1] == NULL) {
				printf("ERROR: %s requires an argument\n", argv[argvStep]);
				return -1;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &nbfrequency)) {
				printf("ERROR: invalid nbfrequency -- %s\n", argv[argvStep + 1]);
				return -1;
			}
			if (processor->getProcessorIdentifier() == PROCESSOR_10H_FAMILY) {
				processor->setNBFrequency(ps, nbfrequency);
				print_stat(processor, ps, "nbfrequency", nbfrequency, PRINT_STAT_FLAG_NODE | PRINT_STAT_FLAG_PSTATE);
				if (processor->getNBFrequency(ps) != nbfrequency)
					printf(" (actual: %d)", processor->getNBFrequency(ps));
				printf("\n\n");
			} else {
				processor->setNBFrequency(nbfrequency);
				print_stat(processor, ps, "nbfrequency", nbfrequency, PRINT_STAT_FLAG_NODE);
				if (processor->getNBFrequency() != nbfrequency)
					printf(" (actual: %d)", processor->getNBFrequency());
				printf("\n\n");
			}
			argvStep++;
			continue;
		}

		//Enables a specified PState for current cores and current nodes
		if (strcmp(argv[argvStep], "-en") == 0) {

			unsigned int pstate;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -en requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &pstate)) { 
				printf("ERROR: -en: invalid P-state -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (pstate >= processor->getPowerStates()) {
				printf("ERROR: -en: P-state must be in 0-%u range\n", processor->getPowerStates() - 1);
				break;
			}
			processor->pStateEnable(pstate);
			argvStep++;
			continue;
		}

		//Disables a specified PState for current cores and current nodes
		if (strcmp(argv[argvStep], "-di") == 0) {

			unsigned int pstate;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -di requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &pstate)) { 
				printf("ERROR: -di: invalid P-state -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (pstate >= processor->getPowerStates()) {
				printf("ERROR: -di: P-state must be in 0-%u range\n", processor->getPowerStates() - 1);
				break;
			}
			processor->pStateDisable(pstate);
			argvStep++;
			continue;
		}

		//Set maximum PState for current nodes
		if (strcmp(argv[argvStep], "-psmax") == 0) {

			unsigned int pstate;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -psmax requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &pstate)) { 
				printf("ERROR: invalid P-state -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (pstate >= processor->getPowerStates()) {
				printf("ERROR: P-state must be in 0-%u range\n", processor->getPowerStates() - 1);
				break;
			}
			processor->setMaximumPState(pstate);
			argvStep++;
			continue;
		}

		//Force transition to a pstate for current cores and current nodes
		if (strcmp(argv[argvStep], "-fo") == 0) {

			unsigned int pstate;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -fo requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &pstate)) { 
				printf("ERROR: -fo: invalid P-state -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (pstate >= processor->getPowerStates() - processor->getBoostStates()) {
				printf("ERROR: -fo: P-state (software P-state) must be in 0-%u range\n", processor->getPowerStates() - processor->getBoostStates() - 1);
				break;
			}
			processor->forcePState(pstate);
			argvStep++;
			continue;
		}

		if (strcmp(argv[argvStep], "-bst") == 0) {

			unsigned int numBoostStates;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -bst requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &numBoostStates)) { 
				printf("ERROR: invalid numBoostStates -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setNumBoostStates(numBoostStates);
			argvStep++;
			continue;
		}

		//Show temperature table
		if (strcmp(argv[argvStep], "-temp") == 0) {

			processorTempStatus(processor);
			continue;
		}

		//Set vsSlamTime for current nodes
		if (strcmp(argv[argvStep], "-slamtime") == 0) {

			unsigned int slamtime;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -slamtime requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &slamtime)) { 
				printf("ERROR: invalid slamtime -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setSlamTime(slamtime);
			argvStep++;
			continue;
		}

		//Set vsAltVIDSlamTime for current nodes
		if (strcmp(argv[argvStep], "-altvidslamtime") == 0) {

			unsigned int altvidslamtime;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -altvidslamtime requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &altvidslamtime)) { 
				printf("ERROR: invalid altvidslamtime -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setAltVidSlamTime(altvidslamtime);
			argvStep++;
			continue;
		}

		//Set Ramp time for StepUpTime for current nodes
		if (strcmp(argv[argvStep], "-rampuptime") == 0) {

			unsigned int rampuptime;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -rampuptime requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &rampuptime)) { 
				printf("ERROR: invalid rampuptime -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setStepUpRampTime(rampuptime);
			argvStep++;
			continue;
		}

		//Set Ramp time for StepDownTime for current nodes
		if (strcmp(argv[argvStep], "-rampdowntime") == 0) {

			unsigned int rampdowntime;

			if (argv[argvStep + 1] == NULL) {
				printf ("ERROR: -rampdowntime requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &rampdowntime)) { 
				printf("ERROR: invalid rampdowntime -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setStepDownRampTime(rampdowntime);
			argvStep++;
			continue;
		}

		if (strcmp(argv[argvStep], "-gettdp") == 0) {

			processor->getTDP();
			continue;
		}

		//Show information about per-family specifications
		if (strcmp(argv[argvStep], "-spec") == 0) {

			processor->showFamilySpecs();
			continue;
		}

		//Show information about DRAM timing register
		if (strcmp(argv[argvStep], "-dram") == 0) {

			processor->showDramTimings();
			continue;
		}

		//Show information about HTC registers status
		if (strcmp(argv[argvStep], "-htc") == 0) {

			processor->showHTC();
			continue;
		}
		
		//Enables HTC Features for current nodes
		if (strcmp(argv[argvStep], "-htcenable") == 0) {

			processor->HTCEnable();
			continue;
		}

		//Disables HTC Features for current nodes
		if (strcmp(argv[argvStep], "-htcdisable") == 0) {

			processor->HTCDisable();
			continue;
		}

		//Set HTC temperature limit for current nodes
		if (strcmp(argv[argvStep], "-htctemplimit") == 0) {

			unsigned int htctemplimit;

			if (argv[argvStep + 1] == NULL) {
				printf("ERROR: -htctemplimit requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &htctemplimit)) { 
				printf("ERROR: invalid htctemplimit -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->HTCsetTempLimit(htctemplimit);
			argvStep++;
			continue;
		}

		//Set HTC hysteresis limit for current nodes
		if (strcmp(argv[argvStep], "-htchystlimit") == 0) {

			unsigned int htchystlimit;

			if (argv[argvStep + 1] == NULL) {
				printf("ERROR: -htchystlimit requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &htchystlimit)) { 
				printf("ERROR: invalid htchystlimit -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->HTCsetHystLimit(htchystlimit);
			argvStep++;
			continue;
		}

		//Set AltVID for current nodes
		if (strcmp(argv[argvStep], "-altvid") == 0) {

			unsigned int altvid;

			if (argv[argvStep + 1] == NULL) {
				printf("ERROR: -altvid requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &altvid)) { 
				printf("ERROR: invalid altvid -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->setAltVid(altvid);
			argvStep++;
			continue;
		}

		//Show information about Hypertransport registers
		if (strcmp(argv[argvStep], "-htstatus") == 0) {

			processor->showHTLink();
			continue;
		}

		//Set Hypertransport Link frequency for current nodes
		if (strcmp(argv[argvStep], "-htset") == 0) {

			unsigned int reg;
			unsigned int value;

			if ((argv[argvStep + 1] == NULL) || (argv[argvStep + 2] == NULL)) {
				printf("ERROR: -htset requires two arguments (register, value)\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &reg)) { 
				printf("ERROR: invalid register -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 2, &value)) { 
				printf("ERROR: invalid value -- %s\n", argv[argvStep + 2]);
				break;
			}
			processor->setHTLinkSpeed(reg, value);
			argvStep += 2;
			continue;
		}

		//Enables PSI_L bit for current nodes
		if (strcmp(argv[argvStep], "-psienable") == 0) {

			processor->setPsiEnabled (true);
			continue;
		}

		//Disables PSI_L bit for current nodes
		if (strcmp(argv[argvStep], "-psidisable") == 0) {

			processor->setPsiEnabled (false);
			continue;
		}

		//Set PSI_L bit threshold for current nodes
		if (strcmp(argv[argvStep], "-psithreshold") == 0) {

			unsigned int psithreshold;

			if (argv[argvStep + 1] == NULL) {
				printf("ERROR: -psithreshold requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &psithreshold)) { 
				printf("ERROR: invalid psithreshold -- %s\n", argv[argvStep + 1]);
				break;
			}
			if (processor->getPsiEnabled() == true) {
				printf("ERROR: PSI enabled; disable PSI before changing PSI threshold\n");
				break;
			}
			printf("WARNING: changing PSI threshold may cause permanent damage to your hardware!\n\n");
			processor->setPsiThreshold(psithreshold);
			argvStep++;
			continue;
		}

		//Set C1E enabled on current nodes and current cores
		if (strcmp(argv[argvStep], "-c1eenable") == 0) {

			processor->setC1EStatus(true);
			continue;
		}

		//Set C1E disabled on current nodes and current cores
		if (strcmp(argv[argvStep], "-c1edisable") == 0) {

			processor->setC1EStatus(false);
			continue;
		}

		//Set Boost state to enabled for supported processors
		if (strcmp(argv[argvStep], "-boostenable") == 0) {	

			processor->setBoost(true);
			continue;
		}

		//Set Boost state to disabled for supported processors
		if (strcmp(argv[argvStep], "-boostdisable") == 0) {

			processor->setBoost(false);
			continue;
		}

		//Goes in temperature monitoring
		if (strcmp(argv[argvStep], "-mtemp") == 0) {

			processorTempMonitoring(processor);
			continue;
		}

		//Goes into Check Mode and controls very fastly if a transition to a wrong pstate happens
		if (strcmp(argv[argvStep], "-CM") == 0) {

			processor->checkMode();
			continue;
		}

		//Allow cyclic parameter auto recall
		if (strcmp(argv[argvStep], "-autorecall") == 0) {

			if (autoRecall == false) {
				autoRecall = true;
				autoRecallTimer = 60;
			}
			continue;
		}

		//Get general info about Performance counters
		if (strcmp(argv[argvStep], "-pcgetinfo") == 0) {

			processor->perfCounterGetInfo();
			continue;
		}

		//Get Performance counter value about a specific performance counter
		if (strcmp(argv[argvStep], "-pcgetvalue") == 0) {

			unsigned int counter;

			if (argv[argvStep + 1] == NULL) {
				printf("ERROR: -pcgetvalue requires an argument\n");
				break;
			}
			if (requireUnsignedInteger(argc, argv, argvStep + 1, &counter)) { 
				printf("ERROR: invalid counter -- %s\n", argv[argvStep + 1]);
				break;
			}
			processor->perfCounterGetValue(counter);
			argvStep++;
			continue;
		}

		//Costantly monitors Performance counter value about a specific performance counter
		if (strcmp(argv[argvStep], "-pcmonitor") == 0) {
			printf("ERROR: -pcmonitor is currently not implemented\n");
			break;
		}

		//Handle -set switch. That is a user friendly way to set up a pstate or a pstate/core
		//with frequency value and voltage value.
		if (strcmp(argv[argvStep], "-set") == 0) {

			parsed_set++;
			
			if (parsed - parsed_set) {
				printf("ERROR: -set can only be used exclusively\n");
				break;
			}
			printf("WARNING: -set is deprecated and will be removed in future versions.\n");
			printf("          Please consider using standalone versions of your sub-commands.\n");
			printf("          Consult the documentation for details.\n\n");
			if ((argvStep = parseSetCommand(processor, argc, argv, argvStep + 1)) == PARSE_WRONG_FORMAT)
				break;

			printf ("*** -set parsing completed\n");
			argvStep--;
			continue;
		}

		//Costantly monitors CPU Usage 
		if (strcmp(argv[argvStep], "-perf-cpuusage") == 0) {

			processor->perfMonitorCPUUsage ();
			continue;
		}

		//Costantly monitors FPU Usage
		if (strcmp(argv[argvStep], "-perf-fpuusage") == 0) {

			processor->perfMonitorFPUUsage ();
			continue;
		}

		//Constantly monitors Data Cache Misaligned Accesses
		if (strcmp(argv[argvStep], "-perf-dcma") == 0) {

			processor->perfMonitorDCMA();
			continue;
		}



		//Open a configuration file
		if (strcmp(argv[argvStep], "-cfgfile") == 0) {

			cfgInstance=new CfgManager (processor, scaler);

			if (cfgInstance->openCfgFile ((char *)argv[argvStep+1])) {
				printf ("Error: invalid configuration file\n");
				free (cfgInstance);
				break;
			}

			errorLine=cfgInstance->parseCfgFile ();

			if (errorLine!=0) {
				printf ("Error: invalid configuration identifier at row %d\n",errorLine);
				free (cfgInstance);
				break;
			}

			free (cfgInstance); 

			argvStep++;
			continue;
		}

		if (strcmp(argv[argvStep], "-scaler") == 0) {

			printf ("Scaler is not active in this version.\n");
			scaler->beginScaling ();
			continue;
		}

		printf("ERROR: invalid argument -- %s\n", argv[argvStep]);
		break;
	}

	free (processor);

	deinitializeCore();

	if (argvStep == argc) {
		printf ("Done.\n");
		return 0;
	}
	return -1;
}