Long-Term Supported Versions

    Innovation Versions

      Development Using powerapi

      (Optional) Source Code Download

      Source code download: https://gitee.com/openeuler/powerapi

      Some interfaces in the source code are experimental and have not been released. RELEASE_MODE in the code indicates whether the interfaces are officially released.

      For details about released APIs, see the API document in the source code repository.

      Installation

      Run the following command to install the powerapi-devel software package and use the provided interfaces for development:

      yum install powerapi-devel
      

      Basic Procedure

      To use query interfaces, you only need to register with powerapi. To use setting interfaces, you need to register with powerapi and request control. Based on service scenarios, the service processes are as follows: Discrete perception service scenario: log callback setting -> registration -> query interface calling -> deregistration Configuration service scenario: log callback setting -> registration -> Control request -> Configuration interface calling -> Control release -> deregistration

      powerapi APIs

      General APIs

      Setting the Log Callback Function

      Definition:

      PWR_API int PWR_SetLogCallback(void(LogCallback)(int level, const char *fmt, va_list vl))
      

      Description:
      Sets the callback logs. After the logs are set, the powerapi library prints the LogCallBack function to the logs. If they are not set, the LogCallBack function is printed to the terminal by default. This API can be called before registration.

      Parameters:

      ParameterTypeDescription
      LogCallBackvoid(*)Log callback function pointer

      Returns:

      TypeDescription
      int0: Succeeded.
      4: Failed. The callback function pointer is empty.

      Setting Server Information

      Definition:

      PWR_API int PWR_SetServerInfo(const char* socketPath)
      

      Description:
      Sets the address of the Unix domain socket communication server.

      Parameters:

      ParameterTypeDescription
      socketPathconst char*Path of the server.

      Returns:

      TypeDescription
      int0: Succeeded.
      4: Failed. The callback function pointer is empty.

      Note:
      The default path of the server socket file is /etc/sysconfig/pwrapis/pwrserver.sock. If you change the default path in the pwrapis configuration file, ensure that the directory permission is 755 and the file permission is 722. After the path is changed, use this interface to specify the new path of the socket before registration. Otherwise, the connection fails.

      Registration

      Definition:

      PWR_API int PWR_Register(void)
      

      Description:
      Registers with the powerapi service.

      Parameters: None
      Returns:

      TypeDescription
      int0: Succeeded.
      1: Failed to initialize the socket client.

      Deregistration

      Definition:

      PWR_API int PWR_UnRegister(void)
      

      Description:
      Deregisters with the powerapi service.

      Parameters: None
      Returns:

      TypeDescription
      int0: Succeeded.

      Requesting Energy Efficiency Control

      Definition:

      PWR_API int PWR_RequestControlAuth(void)
      

      Description:
      Requests control of the system energy efficiency. After an upper-layer application takes over energy efficiency control, the system does not automatically adjust energy efficiency anymore.

      Parameters: None
      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Releasing Energy Efficiency Control

      Definition:

      PWR_API int PWR_ReleaseControlAuth(void)
      

      Description:
      Releases control of the system energy efficiency.

      Parameters: None
      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      CPU

      Obtaining CPU Information

      Definition:

      PWR_API int PWR_CPU_GetInfo(PWR_CPU_Info *cpuInfo)
      

      Description:
      Obtains CPU information, including basic CPU information and NUMA information.

      Parameters:

      ParameterTypeDescription
      cpuinfoPWR_CPU_Info*CPU information.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining the CPU Frequency Ability

      Definition:

      PWR_API int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize)
      

      Description:
      Queries the information about the available CPU frequency domain, governor, and currently used CPU frequency driver.

      Parameters:

      ParameterTypeDescription
      freqAbiPWR_CPU_FreqAbility*CPU frequency ability information
      bufferSizeuint32_tSize of the freqAbi memory block.
      Recommended size:
      sizeof(PWR_CPU_FreqAbility) + CPU core count x (sizeof(int) + 5)
      If the size is too small, only the frequency domain data that can be contained is returned.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining the CPU Frequency Governor

      Definition:

      PWR_API int PWR_CPU_GetFreqGovernor(char gov[], uint32_t size)
      

      Description:
      Obtains the CPU frequency governor in use. By default, the governor of the first frequency domain is obtained.

      Parameters:

      ParameterTypeDescription
      govchar[]Governor name. The value can contain a maximum of 31 characters.
      sizeuint32_tSize of the gov array. The value must be greater than or equal to PWR_MAX_ELEMENT_NAME_LEN(32).

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Setting the CPU Frequency Governor

      Definition:

      PWR_API int PWR_CPU_SetFreqGovernor(const char gov[])
      

      Description:
      Sets the CPU frequency governor in use. (The governor will be set for all frequency domains).

      Parameters:

      ParameterTypeDescription
      govchar[]Governor name. The value can contain a maximum of 31 characters.
      Examples:
      conservative
      ondemand
      userspace
      powersave
      performance
      schedutil
      seep

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining All Attributes of the CPU Frequency Governor

      Definition:

      PWR_API int PWR_CPU_GetFreqGovAttrs(PWR_CPU_FreqGovAttrs *govAttrs)
      

      Description:
      Obtains all attributes of the CPU frequency governor in use.

      Parameters:

      ParameterTypeDescription
      govAttrsPWR_CPU_FreqGovAttrs*Attributes of the frequency governor.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining an Attribute of the CPU Frequency Governor

      Definition:

      PWR_API int PWR_CPU_GetFreqGovAttr(PWR_CPU_FreqGovAttr *govAttr)
      

      Description:
      Obtains the attribute of the current CPU frequency in use. The attribute corresponding to the governor used by the first frequency domain (policy0) is obtained.

      Parameters:

      ParameterTypeDescription
      govAttrsPWR_CPU_FreqGovAttrs*Attributes of the frequency governor.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Setting an Attribute of the CPU Frequency Governor

      Definition:

      PWR_API int PWR_CPU_SetFreqGovAttr(const PWR_CPU_FreqGovAttr *govAttr)
      

      Description:
      Sets the attribute of the current CPU frequency in use. The attribute corresponding to the governor used by the first frequency domain (policy0) is set.

      Parameters:

      ParameterTypeDescription
      govAttrsPWR_CPU_FreqGovAttrs*Attribute of the frequency governor.
      You need to specify the name and value of the attribute to be set.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Note:
      Different governor support different attributes. The attributes supported by the governor are stored in /sys/devices/system/cpu/cpufreq/{gov}/, where {gov} indicates the name of the current governor.

      Obtaining the CPU Frequency Range

      Definition:

      PWR_API int PWR_CPU_GetFreqRange(PWR_CPU_FreqRange *freqRange)
      

      Description:
      Obtains the CPU frequency range. By default, the frequency range of the first frequency domain is obtained.

      Parameters:

      ParameterTypeDescription
      freqRangePWR_CPU_FreqRange*Frequency range to obtain.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Setting the CPU Frequency Range

      Definition:

      PWR_API int PWR_CPU_SetFreqRange(const PWR_CPU_FreqRange *freqRange)
      

      Description:
      Sets the CPU frequency range. The frequency range will be set for all frequency domains.

      Parameters:

      ParameterTypeDescription
      freqRangePWR_CPU_FreqRange*Frequency range to set.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining the Current CPU Frequency

      Definition:

      PWR_API int PWR_CPU_GetFreq(PWR_CPU_CurFreq curFreq[], uint32_t *num, int spec)
      

      Description:
      Obtains the current frequency of the frequency domain.

      Parameters:

      ParameterTypeDescription
      curFreqPWR_CPU_CurFreq[]Frequency information of the current frequency domain of the policy to be queried.
      When spec is set to 1, policyId of the corresponding member needs to be set.
      The current frequency of the frequency domain will be output.
      numuint32_t *Length of the curFreq array, indicating the number of policies to be queried.
      The output is the length of the valid data returned by the system (the smaller value between the actual number of policies and the input num).
      specintWhether to obtain the information about one or more specific frequency domains.
      0: No.
      1: Yes. In this case, you need to set the policyId corresponding to the specific frequency domain in the curFreq member, for example, 32 or 64.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Setting the Current CPU Frequency

      Definition:

      PWR_API int PWR_CPU_SetFreq(const PWR_CPU_CurFreq curFreq[], uint32_t num)
      

      Description:
      Sets the frequency of the frequency domain, which can be set only when the CPU frequency governor is set to userspace.

      Parameters:

      ParameterTypeDescription
      curFreqPWR_CPU_CurFreq[]Frequency domain to be set and its frequency list.
      numuint32_tLength of the curFreq array, indicating the number of policies to be set.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining the CPU Idle Ability and Status Information

      Definition:

      PWR_API int PWR_CPU_GetIdleInfo(PWR_CPU_IdleInfo *idleInfo)
      

      Description:
      Obtains the CPU idle ability and status information.

      Parameters:

      ParameterTypeDescription
      idleInfoPWR_CPU_IdleInfo*CPU idle ability and status information.

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining the CPU Idle Governor

      Definition:

      PWR_API int PWR_CPU_GetIdleGovernor(char idleGov[], uint32_t size)
      

      Description:
      Obtains the CPU idle mode.

      Parameters:

      ParameterTypeDescription
      idleGovchar[]Governor name.
      sizeuint32_tSize of the idleGov buffer. The minimum value is PWR_MAX_ELEMENT_NAME_LEN(32).

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Setting the CPU Idle Governor

      Definition:

      PWR_API int PWR_CPU_SetIdleGovernor(const char idleGov[])
      

      Description:
      Sets the CPU idle mode.

      Parameters:

      ParameterTypeDescription
      idleGovchar[]Governor name, for example:
      ladder
      menu
      teo
      haltpoll

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Obtaining the CPU and DMA Latency

      Definition:

      PWR_API int PWR_CPU_DmaGetLatency(int *latency)
      

      Description:
      Obtains the acceptable latency of the CPU and DMA.

      Parameters:

      ParameterTypeDescription
      latencyint*Latency (us).

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Setting the CPU and DMA Latency

      Definition:

      PWR_API int PWR_CPU_DmaSetLatency(int latency)
      

      Description:
      Sets the acceptable latency of the CPU and DMA.

      Parameters:

      ParameterTypeDescription
      latencyint*Latency (us). Value range: [0, 2000000000]

      Returns:

      TypeDescription
      int0: Succeeded.
      Other value: Failed. See the error codes for details.

      Note:
      The CPU requires different wake-up time in different C-states. The wake-up latency increases as the C-states get deeper. Therefore, the system checks the CPU and DMA latency before entering a C-state. If the latency in the C-state is longer than the CPU and DMA latency, the CPU does not enter the C-state. Reference Wake-up Latency of Each C-state (us)

      C-stateLatency
      C0 POLL0
      C12
      C1E10
      C340
      C6133
      C7S166
      C8300
      C9600
      C102600

      Usage

      Save the following code as powerapi_test.c.

      #include <stdio.h>
      #include <unistd.h>
      #include <signal.h>
      #include <string.h>
      #include <stdlib.h>
      #include <pwrapic/powerapi.h>
      
      #define MAIN_LOOP_INTERVAL 5
      #define TEST_FREQ 2400
      #define TEST_CORE_NUM 128
      #define AVG_LEN_PER_CORE 5
      #define TEST_CPU_DMA_LATENCY 2000
      #define TASK_INTERVAL 1000
      #define TASK_RUN_TIME 10
      #define TEST_FREQ_RANGE_MIN 500
      #define TEST_FREQ_RANGE_MAX 2500
      
      static int g_run = 1;
      
      static void PrintResult(char *function, int ret)
      {
          int length = 24;
          printf("[TEST ]    ");
          printf("%-*s", length, function);
          printf(":");
          if (ret == PWR_SUCCESS) {
              printf("SUCCESS ret: %d\n", ret);
          } else {
              printf("ERROR   ret: %d\n", ret);
          }
      }
      
      enum {
          DEBUG = 0,
          INFO,
          WARNING,
          ERROR
      };
      
      static const char *GetLevelName(int level)
      {
          static char debug[] = "DEBUG";
          static char info[] = "INFO";
          static char warning[] = "WARNING";
          static char error[] = "ERROR";
          switch (level) {
              case DEBUG:
                  return debug;
              case INFO:
                  return info;
              case WARNING:
                  return warning;
              case ERROR:
                  return error;
              default:
                  return info;
          }
      }
      
      void LogCallback(int level, const char *fmt, va_list vl)
      {
          char logLine[4096] = {0};
          char message[4000] = {0};
          int length = 5;
      
          if (vsnprintf(message, sizeof(message) - 1, fmt, vl) < 0) {
              return;
          }
      
          printf("[");
          printf("%-*s", length, GetLevelName(level));
          printf("]    %s\n", message);
      }
      
      static void SignalHandler(int none)
      {
          g_run = 0;
      }
      
      static void SetupSignal(void)
      {
          // regist signal handler
          (void)signal(SIGINT, SignalHandler);
          (void)signal(SIGUSR1, SignalHandler);
          (void)signal(SIGUSR2, SignalHandler);
          (void)signal(SIGTERM, SignalHandler);
          (void)signal(SIGKILL, SignalHandler);
      }
      /************************** COMMON ************************/
      static void TEST_PWR_SetLogCallback(void)
      {
          int ret = -1;
          ret = PWR_SetLogCallback(LogCallback);
          PrintResult("PWR_SetLogCallback", ret);
      }
      
      static void TEST_PWR_SetServerInfo(void)
      {
          int ret = -1;
          char str[] = "/etc/sysconfig/pwrapis/pwrserver.sock";
          ret = PWR_SetServerInfo(str);
          PrintResult("PWR_SetServerInfo", ret);
      }
      
      static void TEST_PWR_Register(void)
      {
          while (PWR_Register() != PWR_SUCCESS) {
              sleep(MAIN_LOOP_INTERVAL);
              PrintResult("PWR_Register", PWR_ERR_COMMON);
              continue;
          }
          PrintResult("PWR_Register", PWR_SUCCESS);
      }
      
      static void TEST_PWR_RequestControlAuth(void)
      {
          int ret = -1;
          ret = PWR_RequestControlAuth();
          PrintResult("PWR_RequestControlAuth", ret);
      }
      /************************** COMMON END************************/
      
      /***************************** CPU ***************************/
      static void TEST_PWR_CPU_GetInfo(void)
      {
          int ret = -1;
          PWR_CPU_Info *info = (PWR_CPU_Info *)malloc(sizeof(PWR_CPU_Info));
          if (!info) {
              return;
          }
          bzero(info, sizeof(PWR_CPU_Info));
          ret = PWR_CPU_GetInfo(info);
          PrintResult("PWR_CPU_GetInfo", ret);
          printf("    arch: %s\n    coreNum: %d\n    maxFreq: %f\n    minFreq: %f\n    "
              "modelName: %s\n    numaNum: %d\n    threadsPerCore: %d\n", info->arch,
              info->coreNum, info->maxFreq, info->minFreq, info->modelName, info->numaNum,
              info->threadsPerCore);
          for (int i = 0; i < info->numaNum; i++) {
              printf("    numa node[%d]  cpuList: %s\n", info->numa[i].nodeNo, info->numa[i].cpuList);
          }
          free(info);
      }
      
      static void TEST_PWR_CPU_GetFreq(void)
      {
          int ret = -1;
          int num = 0;
          int spec = 0;
          int i = 0;
      
          /**
           * Test 1: spec = 0, get all policy freq.
           * Set the num to the number of CPU cores
           * (it is possible that one kernel corresponds to one policy)
           */
          num = TEST_CORE_NUM;
          spec = 0;
          PWR_CPU_CurFreq cpuCurFreq1[num];
          bzero(cpuCurFreq1, num * sizeof(PWR_CPU_CurFreq));
          ret = PWR_CPU_GetFreq(cpuCurFreq1, &num, spec);
          PrintResult("1  PWR_CPU_GetFreq", ret);
          for (i = 0; i < num; i++) {
              printf("    policy[%d]: %lf\n", cpuCurFreq1[i].policyId, cpuCurFreq1[i].curFreq);
          }
      
          /**
           * Test 2: spec = 0 num = 2. get the previous 2 policies freq
           */
          ret = -1;
          // 2: previous 2 policies
          num = 2;
          spec = 0;
          PWR_CPU_CurFreq cpuCurFreq2[num];
          bzero(cpuCurFreq2, num * sizeof(PWR_CPU_CurFreq));
          ret = PWR_CPU_GetFreq(cpuCurFreq2, &num, spec);
          PrintResult("2  PWR_CPU_GetFreq", ret);
          for (i = 0; i < num; i++) {
              printf("    policy[%d]: %lf\n", cpuCurFreq2[i].policyId, cpuCurFreq2[i].curFreq);
          }
      
          /**
           * Test 3: spec = 1, get the two target policy freq
           */
          ret = -1;
          // 2: previous 2 policies
          num = 2;
          spec = 1;
          PWR_CPU_CurFreq cpuCurFreq3[num];
          bzero(cpuCurFreq3, num * sizeof(PWR_CPU_CurFreq));
          cpuCurFreq3[0].policyId = 0;
          // 32 : the Id of the second policy.
          cpuCurFreq3[1].policyId = 32;
          ret = PWR_CPU_GetFreq(cpuCurFreq3, &num, spec);
          PrintResult("3  PWR_CPU_GetFreq", ret);
          for (i = 0; i < num; i++) {
              printf("    policy[%d]: %lf\n", cpuCurFreq3[i].policyId, cpuCurFreq3[i].curFreq);
          }
      }
      
      static void TEST_PWR_CPU_SetFreq(void)
      {
          int ret = -1;
          int num = 1;
          PWR_CPU_CurFreq cpuCurFreq[num];
          bzero(cpuCurFreq, num * sizeof(PWR_CPU_CurFreq));
          cpuCurFreq[0].policyId = 0;
          cpuCurFreq[0].curFreq = TEST_FREQ;
          ret = PWR_CPU_SetFreq(cpuCurFreq, num);
          PrintResult("PWR_CPU_SetFreq", ret);
      
          int spec = 1;
          bzero(cpuCurFreq, num * sizeof(PWR_CPU_CurFreq));
          cpuCurFreq[0].policyId = 0;
          ret = PWR_CPU_GetFreq(cpuCurFreq, &num, spec);
          printf("    current policy[%d]: %lf\n", cpuCurFreq[0].policyId, cpuCurFreq[0].curFreq);
      }
      /*************************** CPU END *************************/
      
      int main(int argc, const char *args[])
      {
          /********** Common **********/
          TEST_PWR_SetServerInfo();
          TEST_PWR_SetLogCallback();
          TEST_PWR_Register();
          TEST_PWR_RequestControlAuth();
      
          /************ CPU ***********/
          TEST_PWR_CPU_GetInfo();
          TEST_PWR_CPU_GetFreq();
          TEST_PWR_CPU_SetFreq();
      
          PWR_ReleaseControlAuth();
          PWR_UnRegister();
          return 0;
      }
      

      Run gcc to compile the program.

      gcc powerapi_test.c -o powerapi_test -lpwrapi
      

      Run the program to view the result.

      ./powerapi_test
      

      Bug Catching

      Buggy Content

      Bug Description

      Submit As Issue

      It's a little complicated....

      I'd like to ask someone.

      PR

      Just a small problem.

      I can fix it online!

      Bug Type
      Specifications and Common Mistakes

      ● Misspellings or punctuation mistakes;

      ● Incorrect links, empty cells, or wrong formats;

      ● Chinese characters in English context;

      ● Minor inconsistencies between the UI and descriptions;

      ● Low writing fluency that does not affect understanding;

      ● Incorrect version numbers, including software package names and version numbers on the UI.

      Usability

      ● Incorrect or missing key steps;

      ● Missing prerequisites or precautions;

      ● Ambiguous figures, tables, or texts;

      ● Unclear logic, such as missing classifications, items, and steps.

      Correctness

      ● Technical principles, function descriptions, or specifications inconsistent with those of the software;

      ● Incorrect schematic or architecture diagrams;

      ● Incorrect commands or command parameters;

      ● Incorrect code;

      ● Commands inconsistent with the functions;

      ● Wrong screenshots.

      Risk Warnings

      ● Lack of risk warnings for operations that may damage the system or important data.

      Content Compliance

      ● Contents that may violate applicable laws and regulations or geo-cultural context-sensitive words and expressions;

      ● Copyright infringement.

      How satisfied are you with this document

      Not satisfied at all
      Very satisfied
      Submit
      Click to create an issue. An issue template will be automatically generated based on your feedback.
      Bug Catching
      编组 3备份