13c3173acSopenharmony_ci/*
23c3173acSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
33c3173acSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43c3173acSopenharmony_ci * you may not use this file except in compliance with the License.
53c3173acSopenharmony_ci * You may obtain a copy of the License at
63c3173acSopenharmony_ci *
73c3173acSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83c3173acSopenharmony_ci *
93c3173acSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103c3173acSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113c3173acSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123c3173acSopenharmony_ci * See the License for the specific language governing permissions and
133c3173acSopenharmony_ci * limitations under the License.
143c3173acSopenharmony_ci */
153c3173acSopenharmony_ci
163c3173acSopenharmony_ci#ifndef GNU_SOURCE
173c3173acSopenharmony_ci#define GNU_SOURCE
183c3173acSopenharmony_ci#endif
193c3173acSopenharmony_ci#include <cerrno>
203c3173acSopenharmony_ci#include <cstdio>
213c3173acSopenharmony_ci#include <unistd.h>
223c3173acSopenharmony_ci#include <sys/ioctl.h>
233c3173acSopenharmony_ci#include <fcntl.h>
243c3173acSopenharmony_ci#include <concurrent_task_log.h>
253c3173acSopenharmony_ci
263c3173acSopenharmony_ci#include "qos_interface.h"
273c3173acSopenharmony_ci
283c3173acSopenharmony_cistatic int TrivalOpenRtgNode(void)
293c3173acSopenharmony_ci{
303c3173acSopenharmony_ci    char fileName[] = "/proc/self/sched_rtg_ctrl";
313c3173acSopenharmony_ci    int fd = open(fileName, O_RDWR);
323c3173acSopenharmony_ci    if (fd < 0) {
333c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open rtg node failed, errno = %{public}d",
343c3173acSopenharmony_ci            getpid(), getuid(), errno);
353c3173acSopenharmony_ci    }
363c3173acSopenharmony_ci    return fd;
373c3173acSopenharmony_ci}
383c3173acSopenharmony_ci
393c3173acSopenharmony_cistatic int TrivalOpenAuthCtrlNode(void)
403c3173acSopenharmony_ci{
413c3173acSopenharmony_ci    char fileName[] = "/dev/auth_ctrl";
423c3173acSopenharmony_ci    int fd = open(fileName, O_RDWR);
433c3173acSopenharmony_ci    if (fd < 0) {
443c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open auth node failed, errno = %{public}d",
453c3173acSopenharmony_ci            getpid(), getuid(), errno);
463c3173acSopenharmony_ci    }
473c3173acSopenharmony_ci    return fd;
483c3173acSopenharmony_ci}
493c3173acSopenharmony_ci
503c3173acSopenharmony_cistatic int TrivalOpenQosCtrlNode(void)
513c3173acSopenharmony_ci{
523c3173acSopenharmony_ci    char fileName[] = "/proc/thread-self/sched_qos_ctrl";
533c3173acSopenharmony_ci    int fd = open(fileName, O_RDWR);
543c3173acSopenharmony_ci    if (fd < 0) {
553c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open qos node failed, errno = %{public}d",
563c3173acSopenharmony_ci            getpid(), getuid(), errno);
573c3173acSopenharmony_ci    }
583c3173acSopenharmony_ci    return fd;
593c3173acSopenharmony_ci}
603c3173acSopenharmony_ci
613c3173acSopenharmony_ciint EnableRtg(bool flag)
623c3173acSopenharmony_ci{
633c3173acSopenharmony_ci    struct RtgEnableData enableData;
643c3173acSopenharmony_ci    char configStr[] = "load_freq_switch:1;sched_cycle:1;frame_max_util:1024";
653c3173acSopenharmony_ci    int ret;
663c3173acSopenharmony_ci
673c3173acSopenharmony_ci    enableData.enable = flag;
683c3173acSopenharmony_ci    enableData.len = sizeof(configStr);
693c3173acSopenharmony_ci    enableData.data = configStr;
703c3173acSopenharmony_ci    int fd = TrivalOpenRtgNode();
713c3173acSopenharmony_ci    if (fd < 0) {
723c3173acSopenharmony_ci        return fd;
733c3173acSopenharmony_ci    }
743c3173acSopenharmony_ci
753c3173acSopenharmony_ci    ret = ioctl(fd, CMD_ID_SET_ENABLE, &enableData);
763c3173acSopenharmony_ci    if (ret < 0) {
773c3173acSopenharmony_ci        printf("set rtg config enable failed.\n");
783c3173acSopenharmony_ci    }
793c3173acSopenharmony_ci
803c3173acSopenharmony_ci    close(fd);
813c3173acSopenharmony_ci
823c3173acSopenharmony_ci    return 0;
833c3173acSopenharmony_ci};
843c3173acSopenharmony_ci
853c3173acSopenharmony_ciint AuthEnable(unsigned int pid, unsigned int uaFlag, unsigned int status)
863c3173acSopenharmony_ci{
873c3173acSopenharmony_ci    struct AuthCtrlData data;
883c3173acSopenharmony_ci    int fd;
893c3173acSopenharmony_ci    int ret;
903c3173acSopenharmony_ci
913c3173acSopenharmony_ci    fd = TrivalOpenAuthCtrlNode();
923c3173acSopenharmony_ci    if (fd < 0) {
933c3173acSopenharmony_ci        return fd;
943c3173acSopenharmony_ci    }
953c3173acSopenharmony_ci
963c3173acSopenharmony_ci    data.pid = pid;
973c3173acSopenharmony_ci    data.rtgUaFlag = uaFlag;
983c3173acSopenharmony_ci    data.qosUaFlag = AF_QOS_DELEGATED;
993c3173acSopenharmony_ci    data.status = status;
1003c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_ENABLE);
1013c3173acSopenharmony_ci
1023c3173acSopenharmony_ci    ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
1033c3173acSopenharmony_ci#ifdef QOS_DEBUG
1043c3173acSopenharmony_ci    if (ret < 0) {
1053c3173acSopenharmony_ci        printf("auth enable failed for pid %u with status %u\n", pid, status);
1063c3173acSopenharmony_ci    }
1073c3173acSopenharmony_ci#endif
1083c3173acSopenharmony_ci    close(fd);
1093c3173acSopenharmony_ci    return ret;
1103c3173acSopenharmony_ci}
1113c3173acSopenharmony_ci
1123c3173acSopenharmony_ciint AuthSwitch(unsigned int pid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status)
1133c3173acSopenharmony_ci{
1143c3173acSopenharmony_ci    struct AuthCtrlData data;
1153c3173acSopenharmony_ci    int fd;
1163c3173acSopenharmony_ci    int ret;
1173c3173acSopenharmony_ci
1183c3173acSopenharmony_ci    fd = TrivalOpenAuthCtrlNode();
1193c3173acSopenharmony_ci    if (fd < 0) {
1203c3173acSopenharmony_ci        return fd;
1213c3173acSopenharmony_ci    }
1223c3173acSopenharmony_ci
1233c3173acSopenharmony_ci    data.pid = pid;
1243c3173acSopenharmony_ci    data.rtgUaFlag = rtgFlag;
1253c3173acSopenharmony_ci    data.qosUaFlag = qosFlag;
1263c3173acSopenharmony_ci    data.status = status;
1273c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
1283c3173acSopenharmony_ci
1293c3173acSopenharmony_ci    ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
1303c3173acSopenharmony_ci#ifdef QOS_DEBUG
1313c3173acSopenharmony_ci    if (ret < 0) {
1323c3173acSopenharmony_ci        printf("auth switch failed for pid %u with status %u\n", pid, status);
1333c3173acSopenharmony_ci    }
1343c3173acSopenharmony_ci#endif
1353c3173acSopenharmony_ci    close(fd);
1363c3173acSopenharmony_ci    return ret;
1373c3173acSopenharmony_ci}
1383c3173acSopenharmony_ci
1393c3173acSopenharmony_ciint AuthDelete(unsigned int pid)
1403c3173acSopenharmony_ci{
1413c3173acSopenharmony_ci    struct AuthCtrlData data;
1423c3173acSopenharmony_ci    int fd;
1433c3173acSopenharmony_ci    int ret;
1443c3173acSopenharmony_ci
1453c3173acSopenharmony_ci    fd = TrivalOpenAuthCtrlNode();
1463c3173acSopenharmony_ci    if (fd < 0) {
1473c3173acSopenharmony_ci        return fd;
1483c3173acSopenharmony_ci    }
1493c3173acSopenharmony_ci
1503c3173acSopenharmony_ci    data.pid = pid;
1513c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_DELETE);
1523c3173acSopenharmony_ci
1533c3173acSopenharmony_ci    ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
1543c3173acSopenharmony_ci#ifdef QOS_DEBUG
1553c3173acSopenharmony_ci    if (ret < 0) {
1563c3173acSopenharmony_ci        printf("auth delete failed for pid %u\n", pid);
1573c3173acSopenharmony_ci    }
1583c3173acSopenharmony_ci#endif
1593c3173acSopenharmony_ci    close(fd);
1603c3173acSopenharmony_ci    return ret;
1613c3173acSopenharmony_ci}
1623c3173acSopenharmony_ci
1633c3173acSopenharmony_ciint AuthPause(unsigned int pid)
1643c3173acSopenharmony_ci{
1653c3173acSopenharmony_ci    struct AuthCtrlData data;
1663c3173acSopenharmony_ci    int fd;
1673c3173acSopenharmony_ci    int ret;
1683c3173acSopenharmony_ci
1693c3173acSopenharmony_ci    fd = TrivalOpenAuthCtrlNode();
1703c3173acSopenharmony_ci    if (fd < 0) {
1713c3173acSopenharmony_ci        return fd;
1723c3173acSopenharmony_ci    }
1733c3173acSopenharmony_ci
1743c3173acSopenharmony_ci    data.pid = pid;
1753c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
1763c3173acSopenharmony_ci    data.rtgUaFlag = 0;
1773c3173acSopenharmony_ci    data.qosUaFlag = AF_QOS_DELEGATED;
1783c3173acSopenharmony_ci    data.status = static_cast<unsigned int>(AuthStatus::AUTH_STATUS_BACKGROUND);
1793c3173acSopenharmony_ci
1803c3173acSopenharmony_ci    ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
1813c3173acSopenharmony_ci#ifdef QOS_DEBUG
1823c3173acSopenharmony_ci    if (ret < 0) {
1833c3173acSopenharmony_ci        printf("auth pause failed for pid %u\n", pid);
1843c3173acSopenharmony_ci    }
1853c3173acSopenharmony_ci#endif
1863c3173acSopenharmony_ci    close(fd);
1873c3173acSopenharmony_ci    return ret;
1883c3173acSopenharmony_ci}
1893c3173acSopenharmony_ci
1903c3173acSopenharmony_ciint AuthGet(unsigned int pid)
1913c3173acSopenharmony_ci{
1923c3173acSopenharmony_ci    struct AuthCtrlData data;
1933c3173acSopenharmony_ci    int fd;
1943c3173acSopenharmony_ci    int ret;
1953c3173acSopenharmony_ci
1963c3173acSopenharmony_ci    fd = TrivalOpenAuthCtrlNode();
1973c3173acSopenharmony_ci    if (fd < 0) {
1983c3173acSopenharmony_ci        return fd;
1993c3173acSopenharmony_ci    }
2003c3173acSopenharmony_ci
2013c3173acSopenharmony_ci    data.pid = pid;
2023c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_GET);
2033c3173acSopenharmony_ci
2043c3173acSopenharmony_ci    ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
2053c3173acSopenharmony_ci    if (ret < 0) {
2063c3173acSopenharmony_ci        close(fd);
2073c3173acSopenharmony_ci        return ret;
2083c3173acSopenharmony_ci    }
2093c3173acSopenharmony_ci    close(fd);
2103c3173acSopenharmony_ci
2113c3173acSopenharmony_ci    return static_cast<int>(data.status);
2123c3173acSopenharmony_ci}
2133c3173acSopenharmony_ci
2143c3173acSopenharmony_ciint AuthEnhance(unsigned int pid, bool enhanceStatus)
2153c3173acSopenharmony_ci{
2163c3173acSopenharmony_ci    int ret = 0;
2173c3173acSopenharmony_ci#ifdef QOS_EXT_ENABLE
2183c3173acSopenharmony_ci    struct AuthCtrlData data;
2193c3173acSopenharmony_ci    int fd = TrivalOpenAuthCtrlNode();
2203c3173acSopenharmony_ci    if (fd < 0) {
2213c3173acSopenharmony_ci        return fd;
2223c3173acSopenharmony_ci    }
2233c3173acSopenharmony_ci
2243c3173acSopenharmony_ci    data.pid = pid;
2253c3173acSopenharmony_ci    data.enhanceStatus = enhanceStatus;
2263c3173acSopenharmony_ci    ret = ioctl(fd, ENHANCE_AUTH_CTRL_OPERATION, &data);
2273c3173acSopenharmony_ci    close(fd);
2283c3173acSopenharmony_ci#endif
2293c3173acSopenharmony_ci    return ret;
2303c3173acSopenharmony_ci}
2313c3173acSopenharmony_ci
2323c3173acSopenharmony_ciint QosApply(unsigned int level)
2333c3173acSopenharmony_ci{
2343c3173acSopenharmony_ci    int tid = gettid();
2353c3173acSopenharmony_ci    int ret;
2363c3173acSopenharmony_ci
2373c3173acSopenharmony_ci    ret = QosApplyForOther(level, tid);
2383c3173acSopenharmony_ci    return ret;
2393c3173acSopenharmony_ci}
2403c3173acSopenharmony_ci
2413c3173acSopenharmony_ciint QosApplyForOther(unsigned int level, int tid)
2423c3173acSopenharmony_ci{
2433c3173acSopenharmony_ci    struct QosCtrlData data;
2443c3173acSopenharmony_ci    int fd;
2453c3173acSopenharmony_ci
2463c3173acSopenharmony_ci    int ret;
2473c3173acSopenharmony_ci
2483c3173acSopenharmony_ci    fd = TrivalOpenQosCtrlNode();
2493c3173acSopenharmony_ci    if (fd < 0) {
2503c3173acSopenharmony_ci        return fd;
2513c3173acSopenharmony_ci    }
2523c3173acSopenharmony_ci
2533c3173acSopenharmony_ci    data.level = level;
2543c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(QosManipulateType::QOS_APPLY);
2553c3173acSopenharmony_ci    data.pid = tid;
2563c3173acSopenharmony_ci
2573c3173acSopenharmony_ci    ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
2583c3173acSopenharmony_ci    if (ret < 0) {
2593c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d apply qos failed, errno = %{public}d", tid, errno);
2603c3173acSopenharmony_ci    }
2613c3173acSopenharmony_ci    close(fd);
2623c3173acSopenharmony_ci    return ret;
2633c3173acSopenharmony_ci}
2643c3173acSopenharmony_ci
2653c3173acSopenharmony_ciint QosLeave(void)
2663c3173acSopenharmony_ci{
2673c3173acSopenharmony_ci    struct QosCtrlData data;
2683c3173acSopenharmony_ci    int fd;
2693c3173acSopenharmony_ci    int ret;
2703c3173acSopenharmony_ci
2713c3173acSopenharmony_ci    fd = TrivalOpenQosCtrlNode();
2723c3173acSopenharmony_ci    if (fd < 0) {
2733c3173acSopenharmony_ci        return fd;
2743c3173acSopenharmony_ci    }
2753c3173acSopenharmony_ci
2763c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE);
2773c3173acSopenharmony_ci    data.pid = gettid();
2783c3173acSopenharmony_ci
2793c3173acSopenharmony_ci    ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
2803c3173acSopenharmony_ci    if (ret < 0) {
2813c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d leave qos failed, errno = %{public}d", gettid(), errno);
2823c3173acSopenharmony_ci    }
2833c3173acSopenharmony_ci    close(fd);
2843c3173acSopenharmony_ci    return ret;
2853c3173acSopenharmony_ci}
2863c3173acSopenharmony_ci
2873c3173acSopenharmony_ciint QosLeaveForOther(int tid)
2883c3173acSopenharmony_ci{
2893c3173acSopenharmony_ci    struct QosCtrlData data;
2903c3173acSopenharmony_ci    int fd;
2913c3173acSopenharmony_ci    int ret;
2923c3173acSopenharmony_ci
2933c3173acSopenharmony_ci    fd = TrivalOpenQosCtrlNode();
2943c3173acSopenharmony_ci    if (fd < 0) {
2953c3173acSopenharmony_ci        return fd;
2963c3173acSopenharmony_ci    }
2973c3173acSopenharmony_ci
2983c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE);
2993c3173acSopenharmony_ci    data.pid = tid;
3003c3173acSopenharmony_ci
3013c3173acSopenharmony_ci    ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
3023c3173acSopenharmony_ci    if (ret < 0) {
3033c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d leave qos failed, errno = %{public}d", tid, errno);
3043c3173acSopenharmony_ci    }
3053c3173acSopenharmony_ci    close(fd);
3063c3173acSopenharmony_ci    return ret;
3073c3173acSopenharmony_ci}
3083c3173acSopenharmony_ci
3093c3173acSopenharmony_ciint QosPolicySet(const struct QosPolicyDatas *policyDatas)
3103c3173acSopenharmony_ci{
3113c3173acSopenharmony_ci    int fd;
3123c3173acSopenharmony_ci    int ret;
3133c3173acSopenharmony_ci
3143c3173acSopenharmony_ci    fd = TrivalOpenQosCtrlNode();
3153c3173acSopenharmony_ci    if (fd < 0) {
3163c3173acSopenharmony_ci        return fd;
3173c3173acSopenharmony_ci    }
3183c3173acSopenharmony_ci
3193c3173acSopenharmony_ci    ret = ioctl(fd, QOS_CTRL_POLICY_OPERATION, policyDatas);
3203c3173acSopenharmony_ci    if (ret < 0) {
3213c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] set qos policy failed, errno = %{public}d", errno);
3223c3173acSopenharmony_ci    }
3233c3173acSopenharmony_ci    close(fd);
3243c3173acSopenharmony_ci    return ret;
3253c3173acSopenharmony_ci}
3263c3173acSopenharmony_ci
3273c3173acSopenharmony_ciint QosGet(int &level)
3283c3173acSopenharmony_ci{
3293c3173acSopenharmony_ci    int tid = gettid();
3303c3173acSopenharmony_ci    return QosGetForOther(tid, level);
3313c3173acSopenharmony_ci}
3323c3173acSopenharmony_ci
3333c3173acSopenharmony_ciint QosGetForOther(int tid, int &level)
3343c3173acSopenharmony_ci{
3353c3173acSopenharmony_ci    int fd;
3363c3173acSopenharmony_ci    int ret = 0;
3373c3173acSopenharmony_ci
3383c3173acSopenharmony_ci    fd = TrivalOpenQosCtrlNode();
3393c3173acSopenharmony_ci    if (fd < 0) {
3403c3173acSopenharmony_ci        return fd;
3413c3173acSopenharmony_ci    }
3423c3173acSopenharmony_ci
3433c3173acSopenharmony_ci    struct QosCtrlData data;
3443c3173acSopenharmony_ci    data.type = static_cast<unsigned int>(QosManipulateType::QOS_GET);
3453c3173acSopenharmony_ci    data.pid = tid;
3463c3173acSopenharmony_ci    data.qos = -1;
3473c3173acSopenharmony_ci
3483c3173acSopenharmony_ci    ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
3493c3173acSopenharmony_ci    if (ret < 0) {
3503c3173acSopenharmony_ci        CONCUR_LOGE("[Interface] task %{public}d get qos failed, errno = %{public}d", tid, errno);
3513c3173acSopenharmony_ci    }
3523c3173acSopenharmony_ci    level = data.qos;
3533c3173acSopenharmony_ci
3543c3173acSopenharmony_ci    close(fd);
3553c3173acSopenharmony_ci    return ret;
3563c3173acSopenharmony_ci}