pm: add two examples for the power management API
https://jira.digi.com/browse/DEL-6659 Signed-off-by: Francisco Gil <francisco.gilmartinez@digi.com>
This commit is contained in:
parent
844d13fec0
commit
0e94c71cfb
|
|
@ -0,0 +1,44 @@
|
||||||
|
#
|
||||||
|
# Copyright 2019, Digi International Inc.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
# PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
#
|
||||||
|
|
||||||
|
BINARYCPU := apix-cpu-example
|
||||||
|
BINARYPM := apix-pm-application
|
||||||
|
|
||||||
|
BINARIES := $(BINARYCPU) $(BINARYPM)
|
||||||
|
|
||||||
|
CFLAGS += -Wall -O0
|
||||||
|
|
||||||
|
CFLAGS += $(shell pkg-config --cflags libdigiapix)
|
||||||
|
LDLIBS += $(shell pkg-config --libs libdigiapix)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: $(BINARIES)
|
||||||
|
|
||||||
|
$(BINARYCPU): apix-cpu-sample.o
|
||||||
|
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $(BINARYCPU)
|
||||||
|
|
||||||
|
|
||||||
|
$(BINARYPM): apix-pm-sample.o
|
||||||
|
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $(BINARYPM)
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: $(BINARIES)
|
||||||
|
install -d $(DESTDIR)/usr/bin
|
||||||
|
install -m 0755 $^ $(DESTDIR)/usr/bin/
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
-rm -f *.o $(BINARIES)
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
Digi APIX Power Management example Applications
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
Example applications to access and manage CPU functions using the Digi APIX library.
|
||||||
|
|
||||||
|
These applications show how to work with different functions and provide different
|
||||||
|
examples to work with the CPU.
|
||||||
|
|
||||||
|
Running the apix-cpu-example application
|
||||||
|
-----------------------
|
||||||
|
Once the binary is in the target, launch the application:
|
||||||
|
|
||||||
|
```
|
||||||
|
# ./apix-cpu-example
|
||||||
|
Example application using libdigiapix CPU support
|
||||||
|
|
||||||
|
Usage: apix-cpu-example [options]
|
||||||
|
|
||||||
|
-l List available frequencies
|
||||||
|
-s <frequency> Set the desired frequency
|
||||||
|
-v Show the current governor
|
||||||
|
-g List available governors
|
||||||
|
-f <governor> Set the desired governor
|
||||||
|
-t List the temperatures of the system
|
||||||
|
-c <temperature> Set the critical temperature
|
||||||
|
-p <temperature> Set the passive temperature
|
||||||
|
-u Get the CPU usage
|
||||||
|
-n Get the number of CPU cores
|
||||||
|
-d <core_number> Disable the selected core
|
||||||
|
-e <core_number> Enable the selected core
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
apix-cpu-example -l
|
||||||
|
apix-cpu-example -f userspace
|
||||||
|
apix-cpu-example -t
|
||||||
|
```
|
||||||
|
|
||||||
|
The application needs a valid argument to run, some of the arguments need additional parameters.
|
||||||
|
|
||||||
|
Running the apix-pm-application application
|
||||||
|
-----------------------
|
||||||
|
Once the binary is in the target, launch the application:
|
||||||
|
|
||||||
|
```
|
||||||
|
# ./apix-pm-application
|
||||||
|
Example application using libdigiapix power management support.
|
||||||
|
This application enables counter measurements in the CPU and GPU
|
||||||
|
in order to reduce the temperature.
|
||||||
|
|
||||||
|
Usage: apix-pm-application [options]
|
||||||
|
|
||||||
|
-c Apply CPU counter measurements
|
||||||
|
-g Apply GPU counter measurements
|
||||||
|
-b Apply CPU & GPU counter measurements
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
apix-pm-application -g
|
||||||
|
apix-pm-application -b
|
||||||
|
```
|
||||||
|
|
||||||
|
This application enables countermeasures in order to reduce the temperature of the CPU.
|
||||||
|
|
||||||
|
If the CPU countermeasures are set, it will select the userspace governor and will set
|
||||||
|
the minimum frequency in the device in order to reduce the temperature.
|
||||||
|
|
||||||
|
If the GPU counter measurements are set, it will reduce the GPU scaler to half of its original value.
|
||||||
|
Note: Some modules such as CC6UL don't have a GPU.
|
||||||
|
|
||||||
|
Compiling the application
|
||||||
|
-------------------------
|
||||||
|
This demo can be compiled using a Digi Embedded Yocto based toolchain. Make
|
||||||
|
sure to source the corresponding toolchain of the platform you are using,
|
||||||
|
for example, for ConnectCore 6UL:
|
||||||
|
```
|
||||||
|
~$ . <DEY-toolchain-path>/environment-setup-cortexa7hf-vfp-neon-dey-linux-gnueabi
|
||||||
|
~$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information, see the [Digi Embedded Yocto](https://github.com/digi-embedded/meta-digi).
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Copyright 2019, Digi International Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019, Digi International Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <libdigiapix/pwr_management.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* usage_and_exit() - Show usage information and exit with 'exitval' return
|
||||||
|
* value
|
||||||
|
*
|
||||||
|
* @name: Application name.
|
||||||
|
* @exitval: The exit code.
|
||||||
|
*/
|
||||||
|
static void usage_and_exit(const char *name, int exitval)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"Example application using libdigiapix power management support\n"
|
||||||
|
"\n"
|
||||||
|
"Usage: %s [options]\n\n"
|
||||||
|
"-l List available frequencies\n"
|
||||||
|
"-s <frequency> Set the desired frequency \n"
|
||||||
|
"-v Show the current governor\n"
|
||||||
|
"-g List available governors\n"
|
||||||
|
"-f <governor> Set the desired governor\n"
|
||||||
|
"-t List the temperatures of the system\n"
|
||||||
|
"-c <temperature> Set the critical temperature in mºC\n"
|
||||||
|
"-p <temperature> Set the passive temperature in mºC\n"
|
||||||
|
"-u Get the CPU usage\n"
|
||||||
|
"-n Get the number of CPU cores\n"
|
||||||
|
"-d <core_number> Disable the selected core\n"
|
||||||
|
"-e <core_number> Enable the selected core\n"
|
||||||
|
"\n"
|
||||||
|
"Examples:\n"
|
||||||
|
"%s -l\n"
|
||||||
|
"%s -f userspace\n"
|
||||||
|
"%s -t\n"
|
||||||
|
"\n", name, name, name, name);
|
||||||
|
|
||||||
|
exit(exitval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_available_governors() - Print the available governors
|
||||||
|
*/
|
||||||
|
static void list_available_governors()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("These are the governors available:\n");
|
||||||
|
for (i = 0; i < MAX_GOVERNORS; i++) {
|
||||||
|
for (i = 0; i < GOVERNOR_SIZE; i++) {
|
||||||
|
if (ldx_cpu_is_governor_available(i) == EXIT_SUCCESS)
|
||||||
|
printf("\t\t\t%s\n", ldx_cpu_get_governor_string_from_type(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_temperatures() - Print the available temperatures
|
||||||
|
*/
|
||||||
|
static void list_temperatures()
|
||||||
|
{
|
||||||
|
printf("Critical temperature %d mºC\n",
|
||||||
|
ldx_cpu_get_critical_trip_point());
|
||||||
|
printf("Passive temperature %d mºC\n",
|
||||||
|
ldx_cpu_get_passive_trip_point());
|
||||||
|
printf("Current temperature %d mºC\n",
|
||||||
|
ldx_cpu_get_current_temp());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list_available_frequencies() - Print the available frequencies
|
||||||
|
*/
|
||||||
|
static void list_available_frequencies()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
available_frequencies_t freq = ldx_cpu_get_available_freq();
|
||||||
|
|
||||||
|
printf("These are the available frequencies:\n");
|
||||||
|
for (i = 0; i < freq.len; i++) {
|
||||||
|
printf("\t\t\t%d\n", freq.data[i]);
|
||||||
|
}
|
||||||
|
ldx_cpu_free_available_freq(freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *name = basename(argv[0]);
|
||||||
|
const char *governor;
|
||||||
|
governor_mode_t governor_mode;
|
||||||
|
int ret = EXIT_FAILURE;
|
||||||
|
int frequency, temperature, usage, core, opt;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "s:f:m:c:d:e:p:gtlunvh ")) > 0) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'l':
|
||||||
|
list_available_frequencies();
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
frequency = strtoul(optarg, NULL, 10);
|
||||||
|
if (ldx_cpu_set_scaling_freq(frequency) == EXIT_FAILURE) {
|
||||||
|
printf("Error setting the scaling frequency to: %d\n", frequency);
|
||||||
|
} else {
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
list_available_governors();
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
governor = ldx_cpu_get_governor_string_from_type(ldx_cpu_get_governor());
|
||||||
|
if (governor != NULL){
|
||||||
|
printf("This is the current governor: %s\n", governor);
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
} else {
|
||||||
|
printf("Unable to get the current governor");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
governor_mode = ldx_cpu_get_governor_type_from_string(optarg);
|
||||||
|
if (governor_mode == GOVERNOR_INVALID) {
|
||||||
|
printf("Invalid governor: %s", optarg);
|
||||||
|
} else {
|
||||||
|
if (ldx_cpu_set_governor(governor_mode) == EXIT_FAILURE) {
|
||||||
|
printf("Unable to set governor: %s\n", optarg);
|
||||||
|
} else {
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
list_temperatures();
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
temperature = strtoul(optarg, NULL, 10);
|
||||||
|
if (ldx_cpu_set_critical_trip_point(temperature) == EXIT_FAILURE) {
|
||||||
|
printf("Unable to set the critical trip point temperature: %d\n", temperature);
|
||||||
|
} else {
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
temperature = strtoul(optarg, NULL, 10);
|
||||||
|
if (ldx_cpu_set_passive_trip_point(temperature) == EXIT_FAILURE)
|
||||||
|
printf("Unable to set the passive trip point temperature: %d\n", temperature);
|
||||||
|
else
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
usage = ldx_cpu_get_usage();
|
||||||
|
if (usage == -1) {
|
||||||
|
printf("Error getting the CPU usage\n");
|
||||||
|
} else {
|
||||||
|
printf("The usage of the CPU is: %d %%\n", usage);
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
core = ldx_cpu_get_number_of_cores();
|
||||||
|
if (core == -1) {
|
||||||
|
printf("Error getting the number of cores\n");
|
||||||
|
} else {
|
||||||
|
printf("The number of CPU cores is: %d\n", core);
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
core = strtoul(optarg, NULL, 10);
|
||||||
|
printf("Disabling core: %d\n", core);
|
||||||
|
if (ldx_cpu_disable_core(core) == EXIT_FAILURE)
|
||||||
|
printf("Cannot disable the core with index: %d\n", core);
|
||||||
|
else
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
core = strtoul(optarg, NULL, 10);
|
||||||
|
printf("Enabling core: %d\n", core);
|
||||||
|
if (ldx_cpu_enable_core(core) == EXIT_FAILURE)
|
||||||
|
printf("Cannot enable the core with index: %d\n", core);
|
||||||
|
else
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage_and_exit(name, EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == EXIT_FAILURE)
|
||||||
|
usage_and_exit(name, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019, Digi International Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <libdigiapix/pwr_management.h>
|
||||||
|
|
||||||
|
#define CPU_SAMPLING_TIME 6
|
||||||
|
#define MAX_SAMPLES 10
|
||||||
|
/*
|
||||||
|
* usage_and_exit() - Show usage information and exit with 'exitval' return
|
||||||
|
* value
|
||||||
|
*
|
||||||
|
* @name: Application name.
|
||||||
|
* @exitval: The exit code.
|
||||||
|
*/
|
||||||
|
static void usage_and_exit(const char *name, int exitval)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"Example application using libdigiapix power management support. \n"
|
||||||
|
"This application enables counter measurements in the CPU and GPU\n"
|
||||||
|
"in order to reduce the temperature.\n"
|
||||||
|
"\n"
|
||||||
|
"Usage: %s [options]\n\n"
|
||||||
|
"-c Apply CPU counter measurements \n"
|
||||||
|
"-g Apply GPU counter measurements \n"
|
||||||
|
"-b Apply CPU & GPU counter measurements \n"
|
||||||
|
"\n"
|
||||||
|
"Examples:\n"
|
||||||
|
"%s -g\n"
|
||||||
|
"%s -b\n"
|
||||||
|
"\n", name, name, name);
|
||||||
|
|
||||||
|
exit(exitval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* verify_temperature_reduction() - Print the current temperature during
|
||||||
|
* CPU_SAMPLING_TIME * MAX_SAMPLES seconds
|
||||||
|
*
|
||||||
|
* This function prints the temperature each CPU_SAMPLING_TIME seconds.
|
||||||
|
*
|
||||||
|
* Return: EXIT_SUCCESS on success, EXIT_FAILURE if something fails.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int verify_temperature_reduction()
|
||||||
|
{
|
||||||
|
int i, temperature;
|
||||||
|
|
||||||
|
printf("Checking if the temperature is being reduced...\n");
|
||||||
|
for (i = 0; i < MAX_SAMPLES; i++) {
|
||||||
|
temperature = ldx_cpu_get_current_temp();
|
||||||
|
|
||||||
|
if (temperature == -1) {
|
||||||
|
printf("Error getting the temperature\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current temperature: %d \n", temperature);
|
||||||
|
sleep(CPU_SAMPLING_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* apply_countermeasurements() - Apply counter measurements to reduce the temperature
|
||||||
|
*
|
||||||
|
* @gpu: 1 to enable the gpu counter measurements.
|
||||||
|
* @cpu: 1 to enable the cpu counter measurements.
|
||||||
|
*
|
||||||
|
* This function reduces the GPU multiplier to half of its value if
|
||||||
|
* This function reduces the GPU multiplier to half its value if
|
||||||
|
* the gpu value is enabled.
|
||||||
|
*
|
||||||
|
* This function reduces the CPU frequency to the minimum if the cpu value
|
||||||
|
* is enabled.
|
||||||
|
*
|
||||||
|
* Return: EXIT_SUCCESS on success, EXIT_FAILURE if something fails.
|
||||||
|
*/
|
||||||
|
static int apply_countermeasurements(int gpu, int cpu)
|
||||||
|
{
|
||||||
|
governor_mode_t governor;
|
||||||
|
int freq;
|
||||||
|
int ret = EXIT_SUCCESS;
|
||||||
|
int gpu_multiplier;
|
||||||
|
|
||||||
|
if (gpu) {
|
||||||
|
gpu_multiplier = ldx_gpu_get_multiplier();
|
||||||
|
if (gpu_multiplier == -1) {
|
||||||
|
printf("Error getting the gpu multiplier, verify that your platform has a GPU\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ldx_gpu_set_multiplier(gpu_multiplier / 2) == EXIT_FAILURE) {
|
||||||
|
printf("Error setting the gpu multiplier to %d\n", gpu_multiplier / 2);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpu) {
|
||||||
|
governor = ldx_cpu_get_governor();
|
||||||
|
|
||||||
|
if (governor == GOVERNOR_INVALID) {
|
||||||
|
printf("Error getting governor\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only with the 'userspace' governor can we modify and manage the frequency */
|
||||||
|
if (ldx_cpu_set_governor(ldx_cpu_get_governor_type_from_string("userspace"))) {
|
||||||
|
printf("Error setting the 'userspace' governor\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
freq = ldx_cpu_get_scaling_freq();
|
||||||
|
|
||||||
|
if (freq == -1) {
|
||||||
|
printf("Error getting the current frequency, restoring the previous governor\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ldx_cpu_set_scaling_freq(ldx_cpu_get_min_scaling_freq()) == EXIT_FAILURE) {
|
||||||
|
printf("Error setting the scaling frequency\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = verify_temperature_reduction();
|
||||||
|
|
||||||
|
if (cpu) {
|
||||||
|
/* Restore the frequency */
|
||||||
|
if (ldx_cpu_set_scaling_freq(freq)) {
|
||||||
|
printf("Error restoring the previous frequency\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
/* Restore CPU parameters */
|
||||||
|
if (cpu) {
|
||||||
|
if (ldx_cpu_set_governor(governor) == EXIT_FAILURE) {
|
||||||
|
printf("Error restoring the governor\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore GPU parameters */
|
||||||
|
if (gpu) {
|
||||||
|
if (ldx_gpu_set_multiplier(gpu_multiplier)){
|
||||||
|
printf("Error restoring the gpu multiplier\n");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *name = basename(argv[0]);
|
||||||
|
int opt;
|
||||||
|
int cpu = 0;
|
||||||
|
int gpu = 0;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "gcbh")) > 0) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'g':
|
||||||
|
gpu = 1;
|
||||||
|
printf("Applying GPU counter measurements\n");
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
cpu = 1;
|
||||||
|
printf("Applying CPU counter measurements\n");
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
gpu = 1;
|
||||||
|
cpu = 1;
|
||||||
|
printf("Applying GPU & CPU counter measurements\n");
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage_and_exit(name, EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cpu == 1 || gpu == 1){
|
||||||
|
return apply_countermeasurements(gpu, cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
usage_and_exit(name, EXIT_FAILURE);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue