• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef FFRT_CO_BACKTRACE_OH_ENABLE
17 #include <dlfcn.h>
18 #include <sstream>
19 #include "libunwind.h"
20 #include "backtrace_local.h"
21 #endif
22 #include "dm/dependence_manager.h"
23 #include "util/slab.h"
24 #include "internal_inc/osal.h"
25 #include "tm/task_factory.h"
26 #include "tm/cpu_task.h"
27 
28 namespace ffrt {
29 static std::atomic_uint64_t s_gid(0);
TaskBase()30 TaskBase::TaskBase() : gid(++s_gid) {}
31 
SetQos(QoS & new_qos)32 void CPUEUTask::SetQos(QoS& new_qos)
33 {
34     if (new_qos == qos_inherit) {
35         if (!this->IsRoot()) {
36             this->qos = parent->qos;
37         }
38         FFRT_LOGD("Change task %s QoS %d", label.c_str(), this->qos());
39     } else {
40         this->qos = new_qos;
41     }
42 }
43 
freeMem()44 void CPUEUTask::freeMem()
45 {
46     BboxCheckAndFreeze();
47     ffrt::TaskFactory::Free(this);
48 }
49 
CPUEUTask(const task_attr_private * attr,CPUEUTask * parent,const uint64_t & id,const QoS & qos)50 CPUEUTask::CPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id,
51     const QoS &qos)
52     : parent(parent), rank(id), qos(qos)
53 {
54     wue = nullptr;
55     fq_we.task = this;
56     if (attr && !attr->name_.empty()) {
57         label = attr->name_;
58     } else if (IsRoot()) {
59         label = "root";
60     } else if (parent->parent == nullptr) {
61         label = "t" + std::to_string(rank);
62     } else {
63         label = parent->label + "." + std::to_string(rank);
64     }
65     if (!IsRoot()) {
66         FFRT_SUBMIT_MARKER(label, gid);
67     }
68     FFRT_LOGD("create task name:%s gid=%lu", label.c_str(), gid);
69 }
70 
71 #ifdef FFRT_CO_BACKTRACE_OH_ENABLE
DumpTask(CPUEUTask * task,std::string & stackInfo,uint8_t flag)72 void CPUEUTask::DumpTask(CPUEUTask* task, std::string& stackInfo, uint8_t flag)
73 {
74     unw_context_t ctx;
75     unw_cursor_t unw_cur;
76     unw_proc_info_t unw_proc;
77 
78     if (ExecuteCtx::Cur()->task == task || task == nullptr) {
79         if (flag == 0) {
80             OHOS::HiviewDFX::PrintTrace(-1);
81         } else {
82             OHOS::HiviewDFX::GetBacktrace(stackInfo, false);
83         }
84         return;
85     } else {
86         memset(&ctx, 0, sizeof(ctx));
87 #if defined(__aarch64__)
88         ctx.uc_mcontext.regs[UNW_AARCH64_X29] = task->coRoutine->ctx.regs[10];
89         ctx.uc_mcontext.sp = task->coRoutine->ctx.regs[13];
90         ctx.uc_mcontext.pc = task->coRoutine->ctx.regs[11];
91 #elif defined(__x86_64__)
92         ctx.uc_mcontext.gregs[REG_RBX] = task->coRoutine->ctx.regs[0];
93         ctx.uc_mcontext.gregs[REG_RBP] = task->coRoutine->ctx.regs[1];
94         ctx.uc_mcontext.gregs[REG_RSP] = task->coRoutine->ctx.regs[6];
95         ctx.uc_mcontext.gregs[REG_RIP] = *(reinterpret_cast<greg_t *>(ctx.uc_mcontext.gregs[REG_RSP] - 8));
96 #elif defined(__arm__)
97         ctx.regs[13] = task->coRoutine->ctx.regs[0]; /* sp */
98         ctx.regs[15] = task->coRoutine->ctx.regs[1]; /* pc */
99         ctx.regs[14] = task->coRoutine->ctx.regs[1]; /* lr */
100         ctx.regs[11] = task->coRoutine->ctx.regs[10]; /* fp */
101 #endif
102     }
103 
104     int ret;
105     int frame_id = 0;
106     ret = unw_init_local(&unw_cur, &ctx);
107     if (ret < 0) {
108         return;
109     }
110 
111     Dl_info info;
112     unw_word_t prevPc = 0;
113     unw_word_t offset;
114     char symbol[512];
115     std::ostringstream ss;
116     do {
117         ret = unw_get_proc_info(&unw_cur, &unw_proc);
118         if (ret) {
119             break;
120         }
121 
122         if (prevPc == unw_proc.start_ip) {
123             break;
124         }
125 
126         prevPc = unw_proc.start_ip;
127 
128         ret = dladdr(reinterpret_cast<void *>(unw_proc.start_ip), &info);
129         if (!ret) {
130             break;
131         }
132 
133         memset(symbol, 0, sizeof(symbol));
134         if (unw_get_proc_name(&unw_cur, symbol, sizeof(symbol), &offset) == 0) {
135             if (flag == 0) {
136                 FFRT_LOGE("FFRT | #%d pc: %lx %s(%p) %s", frame_id, unw_proc.start_ip, info.dli_fname,
137                           (unw_proc.start_ip - reinterpret_cast<unw_word_t>(info.dli_fbase)), symbol);
138             } else {
139                 ss << "FFRT | #" << frame_id << " pc: " << unw_proc.start_ip << " " << info.dli_fname;
140                 ss << "(" << (unw_proc.start_ip - reinterpret_cast<unw_word_t>(info.dli_fbase)) << ") ";
141                 ss << std::string(symbol, strlen(symbol)) <<std::endl;
142             }
143         } else {
144             if (flag == 0) {
145                 FFRT_LOGE("FFRT | #%d pc: %lx %s(%p)", frame_id, unw_proc.start_ip, info.dli_fname,
146                           (unw_proc.start_ip - reinterpret_cast<unw_word_t>(info.dli_fbase)));
147             } else {
148                 ss << "FFRT | #" << frame_id << " pc: " << unw_proc.start_ip << " " << info.dli_fname;
149                 ss << "(" << (unw_proc.start_ip - reinterpret_cast<unw_word_t>(info.dli_fbase)) << ")";
150                 ss << std::endl;
151             }
152         }
153         ++frame_id;
154     } while (unw_step(&unw_cur) > 0);
155 
156     if (flag != 0) {
157         stackInfo = ss.str();
158     }
159     return;
160 }
161 #endif
162 } /* namespace ffrt */