• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "rs_graphic_test_profiler_thread.h"
17 
18 #include <securec.h>
19 #include <sys/un.h>
20 #include <unistd.h>
21 
22 #include "rs_graphic_test_utils.h"
23 #ifdef RS_PROFILER_ENABLED
24 #include "rs_profiler_packet.h"
25 #endif
26 
27 namespace OHOS {
28 namespace Rosen {
29 #ifdef RS_PROFILER_ENABLED
30 constexpr int64_t INIT_WAIT_TIME = 50;
31 constexpr int64_t SOCKET_REFRESH_TIME = 20;
32 constexpr int SOCKET_CONNECT_MAX_NUM = 10000;
33 const std::string RESPOND_PAUSE_AT = "PlaybackPauseAt OK";
34 const std::string RESPOND_PLAYBACK_PREPARE = "awake_frame 0";
35 
~RSGraphicTestProfilerThread()36 RSGraphicTestProfilerThread::~RSGraphicTestProfilerThread()
37 {
38     Stop();
39 }
40 
Start()41 void RSGraphicTestProfilerThread::Start()
42 {
43     system("param set persist.graphic.profiler.enabled 1");
44     WaitTimeout(INIT_WAIT_TIME);
45     runnig_ = true;
46     thread_ = std::thread(&RSGraphicTestProfilerThread::MainLoop, this);
47 }
48 
Stop()49 void RSGraphicTestProfilerThread::Stop()
50 {
51     system("param set persist.graphic.profiler.enabled 0");
52     if (runnig_) {
53         runnig_ = false;
54         cv_.notify_all();
55     }
56     if (socket_ != -1) {
57         close(socket_);
58         socket_ = -1;
59     }
60     if (thread_.joinable()) {
61         thread_.join();
62     }
63 }
64 
SendCommand(const std::string command,int outTime)65 void RSGraphicTestProfilerThread::SendCommand(const std::string command, int outTime)
66 {
67     {
68         std::unique_lock lock(queue_mutex_);
69         message_queue_.push(command);
70     }
71     if (outTime > 0) {
72         std::unique_lock lock(wait_mutex_);
73         waitReceive_ = true;
74         cv_.wait_for(lock, std::chrono::milliseconds(outTime), [&] { return !waitReceive_; });
75     }
76 }
77 
MainLoop()78 void RSGraphicTestProfilerThread::MainLoop()
79 {
80     socket_ = socket(AF_UNIX, SOCK_STREAM, 0);
81     if (socket_ == -1) {
82         std::cout << "profiler socket create failed" << std::endl;
83         return;
84     }
85 
86     const std::string socketName = "render_service_5050";
87     sockaddr_un address {};
88     address.sun_family = AF_UNIX;
89     address.sun_path[0] = 0;
90     ::memmove_s(address.sun_path + 1, sizeof(address.sun_path) - 1, socketName.data(), socketName.size());
91     const size_t addressSize = offsetof(sockaddr_un, sun_path) + socketName.size() + 1;
92 
93     int tryNum = 1;
94     while (connect(socket_, reinterpret_cast<struct sockaddr*>(&address), addressSize) < 0) {
95         std::cout << "profiler socket connect failed, connect:" + std::to_string(tryNum) << std::endl;
96         tryNum++;
97         if (tryNum > SOCKET_CONNECT_MAX_NUM) {
98             std::cout << "profiler socket connect failed" << std::endl;
99             close(socket_);
100             socket_ = -1;
101             return;
102         }
103     }
104     std::cout << "profiler socket connect success" << std::endl;
105     runnig_ = true;
106     while (runnig_) {
107         {
108             std::unique_lock lock(queue_mutex_);
109             cv_.wait_for(lock, std::chrono::milliseconds(SOCKET_REFRESH_TIME), [this] { return !runnig_; });
110         }
111         SendMessage();
112         RecieveMessage();
113     }
114     close(socket_);
115 }
116 
SendMessage()117 void RSGraphicTestProfilerThread::SendMessage()
118 {
119     std::string message;
120     {
121         std::lock_guard<std::mutex> lock(queue_mutex_);
122         if (!message_queue_.empty()) {
123             message = message_queue_.front();
124             message_queue_.pop();
125         }
126     }
127     if (message.empty()) {
128         return;
129     }
130     Packet packet(Packet::COMMAND);
131     packet.Write(message);
132     auto data = packet.Release();
133     const char* bytes = reinterpret_cast<const char*>(data.data());
134     size_t size = data.size();
135     size_t sent = 0;
136     while (sent < size) {
137         const ssize_t sentBytes = send(socket_, bytes, size - sent, 0);
138         if ((sentBytes <= 0) && (errno != EINTR)) {
139             std::cout << "profiler socket send failed:" + std::to_string(sentBytes) << std::endl;
140             return;
141         }
142         auto actualSentBytes = static_cast<size_t>(sentBytes);
143         sent += actualSentBytes;
144         bytes += actualSentBytes;
145     }
146 }
147 
RecieveMessage()148 void RSGraphicTestProfilerThread::RecieveMessage()
149 {
150     Packet packet { Packet::UNKNOWN };
151     auto wannaReceive = Packet::HEADER_SIZE;
152     RecieveHeader(packet.Begin(), wannaReceive);
153     if (wannaReceive == 0) {
154         std::cout << "profiler socket recieve header failed" << std::endl;
155         return;
156     }
157     const size_t size = packet.GetPayloadLength();
158     if (size == 0) {
159         return;
160     }
161 
162     std::vector<char> data;
163     data.resize(size);
164     size_t received = 0;
165     char* bytes = static_cast<char*>(data.data());
166     while (received < size) {
167         const ssize_t receivedBytes = recv(socket_, bytes, size - received, 0);
168         if ((receivedBytes == -1) && (errno != EINTR)) {
169             std::cout << "profiler socket recieve failed" + std::to_string(receivedBytes) << std::endl;
170             return;
171         }
172         auto actualReceivedBytes = static_cast<size_t>(receivedBytes);
173         received += actualReceivedBytes;
174         bytes += actualReceivedBytes;
175     }
176 
177     if (packet.GetType() == Packet::LOG) {
178         std::string out(data.begin(), data.end());
179         std::cout << out << std::endl;
180         if (waitReceive_) {
181             bool reveive = IsReceiveWaitMessage(out);
182             if (reveive) {
183                 std::unique_lock lock(wait_mutex_);
184                 waitReceive_ = false;
185                 cv_.notify_one();
186             }
187         }
188     }
189 }
190 
IsReceiveWaitMessage(const std::string & message)191 bool RSGraphicTestProfilerThread::IsReceiveWaitMessage(const std::string& message)
192 {
193     return (message == RESPOND_PAUSE_AT || message == RESPOND_PLAYBACK_PREPARE);
194 }
195 
RecieveHeader(void * data,size_t & size)196 bool RSGraphicTestProfilerThread::RecieveHeader(void* data, size_t& size)
197 {
198     if (!data || (size == 0)) {
199         return true;
200     }
201 
202     const ssize_t receivedBytes = recv(socket_, static_cast<char*>(data), size, 0);
203     if (receivedBytes > 0) {
204         size = static_cast<size_t>(receivedBytes);
205     } else {
206         size = 0;
207         if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR)) {
208             return true;
209         }
210         std::cout << "profiler socket recieve header failed" << std::endl;
211         return false;
212     }
213     return true;
214 }
215 #endif
216 } // namespace Rosen
217 } // namespace OHOS
218