1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <cstdlib>
17#include <unistd.h>
18#include "concurrent_task_log.h"
19#if !defined(CROSS_PLATFORM)
20#include "parameters.h"
21#endif
22#include "qos_interface.h"
23#include "qos.h"
24using namespace OHOS::ConcurrentTask;
25
26static constexpr int ERROR_NUM = -1;
27
28namespace OHOS {
29namespace QOS {
30QosController& QosController::GetInstance()
31{
32    static QosController instance;
33    return instance;
34}
35
36int QosController::SetThreadQosForOtherThread(enum QosLevel level, int tid)
37{
38#if !defined(CROSS_PLATFORM)
39    bool qosEnable = OHOS::system::GetBoolParameter("persist.qosmanager.setQos.on", true);
40    if (!qosEnable) {
41        CONCUR_LOGD("[Qos] qoslevel %{public}d apply for tid %{public}d disable", static_cast<int>(level), tid);
42        return 0;
43    }
44#endif
45    int qos = static_cast<int>(level);
46    if (level < QosLevel::QOS_BACKGROUND || level >= QosLevel::QOS_MAX) {
47        CONCUR_LOGE("[Qos] invalid qos level %{public}d", qos);
48        return ERROR_NUM;
49    }
50    int ret = QosApplyForOther(qos, tid);
51    if (ret == 0) {
52        CONCUR_LOGD("[Qos] qoslevel %{public}d apply for tid %{public}d success", qos, tid);
53    } else {
54        CONCUR_LOGD("[Qos] qoslevel %{public}d apply for tid %{public}d failure", qos, tid);
55    }
56
57    return ret;
58}
59
60int QosController::ResetThreadQosForOtherThread(int tid)
61{
62#if !defined(CROSS_PLATFORM)
63    bool qosEnable = OHOS::system::GetBoolParameter("persist.qosmanager.setQos.on", true);
64    if (!qosEnable) {
65        CONCUR_LOGD("[Qos] qoslevel reset disable for tid %{public}d.", tid);
66        return 0;
67    }
68#endif
69    int ret = QosLeaveForOther(tid);
70    if (ret == 0) {
71        CONCUR_LOGD("[Qos] qoslevel reset for tid %{public}d success", tid);
72    } else {
73        CONCUR_LOGD("[Qos] qoslevel reset for tid %{public}d failure", tid);
74    }
75
76    return ret;
77}
78
79int QosController::GetThreadQosForOtherThread(enum QosLevel &level, int tid)
80{
81    int qos = -1;
82    int ret = QosGetForOther(tid, qos);
83    if (ret == 0) {
84        if (qos < static_cast<int>(QosLevel::QOS_BACKGROUND) ||
85                    qos >= static_cast<int>(QosLevel::QOS_MAX)) {
86            CONCUR_LOGE("[Qos] not set qoslevel for tid %{public}d", tid);
87            return ERROR_NUM;
88        }
89        CONCUR_LOGD("[Qos] qoslevel get for tid %{public}d success", tid);
90        level = static_cast<QosLevel>(qos);
91        return ret;
92    } else {
93        CONCUR_LOGD("[Qos] qoslevel get for tid %{public}d failure", tid);
94        return ret;
95    }
96}
97
98int SetThreadQos(enum QosLevel level)
99{
100    int tid = gettid();
101    return QosController::GetInstance().SetThreadQosForOtherThread(level, tid);
102}
103
104int SetQosForOtherThread(enum QosLevel level, int tid)
105{
106    return QosController::GetInstance().SetThreadQosForOtherThread(level, tid);
107}
108
109int ResetThreadQos()
110{
111    int tid = gettid();
112    return QosController::GetInstance().ResetThreadQosForOtherThread(tid);
113}
114
115int ResetQosForOtherThread(int tid)
116{
117    return QosController::GetInstance().ResetThreadQosForOtherThread(tid);
118}
119
120int GetThreadQos(enum QosLevel &level)
121{
122    return QosController::GetInstance().GetThreadQosForOtherThread(level, gettid());
123}
124
125int GetQosForOtherThread(enum QosLevel &level, int tid)
126{
127    return QosController::GetInstance().GetThreadQosForOtherThread(level, tid);
128}
129} // namespace QOS
130} // namespace OHOS
131