106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci 1606f6ba60Sopenharmony_ci#include "buffer_writer.h" 1706f6ba60Sopenharmony_ci#include "command_poller.h" 1806f6ba60Sopenharmony_ci#include "common_types.pb.h" 1906f6ba60Sopenharmony_ci#include "logging.h" 2006f6ba60Sopenharmony_ci#include "plugin_service_types.pb.h" 2106f6ba60Sopenharmony_ci#include "share_memory_allocator.h" 2206f6ba60Sopenharmony_ci 2306f6ba60Sopenharmony_ci#include <algorithm> 2406f6ba60Sopenharmony_ci#include <cinttypes> 2506f6ba60Sopenharmony_ci#include <thread> 2606f6ba60Sopenharmony_ci#include <unistd.h> 2706f6ba60Sopenharmony_ci 2806f6ba60Sopenharmony_ciusing namespace OHOS::Developtools::Profiler; 2906f6ba60Sopenharmony_ci 3006f6ba60Sopenharmony_ciBufferWriter::BufferWriter(std::string name, 3106f6ba60Sopenharmony_ci std::string version, 3206f6ba60Sopenharmony_ci uint32_t size, 3306f6ba60Sopenharmony_ci int smbFd, 3406f6ba60Sopenharmony_ci int eventFd, 3506f6ba60Sopenharmony_ci uint32_t pluginId) 3606f6ba60Sopenharmony_ci : pluginName_(name), pluginVersion_(version) 3706f6ba60Sopenharmony_ci{ 3806f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "%s:%s %d [%d] [%d]", __func__, name.c_str(), size, smbFd, eventFd); 3906f6ba60Sopenharmony_ci shareMemoryBlock_ = ShareMemoryAllocator::GetInstance().CreateMemoryBlockRemote(name, size, smbFd); 4006f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr) { 4106f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "%s:create shareMemoryBlock_ failed!", __func__); 4206f6ba60Sopenharmony_ci } 4306f6ba60Sopenharmony_ci eventNotifier_ = EventNotifier::CreateWithFd(eventFd); 4406f6ba60Sopenharmony_ci pluginId_ = pluginId; 4506f6ba60Sopenharmony_ci lastFlushTime_ = std::chrono::steady_clock::now(); 4606f6ba60Sopenharmony_ci if (shareMemoryBlock_ != nullptr) { 4706f6ba60Sopenharmony_ci writeCtx_ = reinterpret_cast<RandomWriteCtx*>(shareMemoryBlock_->GetCtx()); 4806f6ba60Sopenharmony_ci profilerPluginData_ = ProtoEncoder::ProfilerPluginData(writeCtx_); 4906f6ba60Sopenharmony_ci } 5006f6ba60Sopenharmony_ci} 5106f6ba60Sopenharmony_ci 5206f6ba60Sopenharmony_ciBufferWriter::~BufferWriter() 5306f6ba60Sopenharmony_ci{ 5406f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "%s:destroy eventfd = %d!", __func__, eventNotifier_ ? eventNotifier_->GetFd() : -1); 5506f6ba60Sopenharmony_ci eventNotifier_ = nullptr; 5606f6ba60Sopenharmony_ci ShareMemoryAllocator::GetInstance().ReleaseMemoryBlockRemote(pluginName_); 5706f6ba60Sopenharmony_ci} 5806f6ba60Sopenharmony_ci 5906f6ba60Sopenharmony_civoid BufferWriter::Report() const 6006f6ba60Sopenharmony_ci{ 6106f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "%s:stats B: %" PRIu64 ", P: %d, W:%" PRIu64 ", F: %d", __func__, 6206f6ba60Sopenharmony_ci bytesCount_.load(), bytesPending_.load(), writeCount_.load(), flushCount_.load()); 6306f6ba60Sopenharmony_ci} 6406f6ba60Sopenharmony_ci 6506f6ba60Sopenharmony_civoid BufferWriter::DoStats(long bytes) 6606f6ba60Sopenharmony_ci{ 6706f6ba60Sopenharmony_ci ++writeCount_; 6806f6ba60Sopenharmony_ci bytesCount_ += static_cast<uint64_t>(bytes); 6906f6ba60Sopenharmony_ci bytesPending_ += static_cast<uint32_t>(bytes); 7006f6ba60Sopenharmony_ci} 7106f6ba60Sopenharmony_ci 7206f6ba60Sopenharmony_cilong BufferWriter::Write(const void* data, size_t size) 7306f6ba60Sopenharmony_ci{ 7406f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr || data == nullptr || size == 0) { 7506f6ba60Sopenharmony_ci return false; 7606f6ba60Sopenharmony_ci } 7706f6ba60Sopenharmony_ci ProfilerPluginData pluginData; 7806f6ba60Sopenharmony_ci pluginData.set_name(pluginName_); 7906f6ba60Sopenharmony_ci pluginData.set_version(pluginVersion_); 8006f6ba60Sopenharmony_ci pluginData.set_status(0); 8106f6ba60Sopenharmony_ci pluginData.set_data(data, size); 8206f6ba60Sopenharmony_ci 8306f6ba60Sopenharmony_ci struct timespec ts = { 0, 0 }; 8406f6ba60Sopenharmony_ci clock_gettime(clockId_, &ts); 8506f6ba60Sopenharmony_ci 8606f6ba60Sopenharmony_ci pluginData.set_clock_id(static_cast<ProfilerPluginData_ClockId>(clockId_)); 8706f6ba60Sopenharmony_ci pluginData.set_tv_sec(ts.tv_sec); 8806f6ba60Sopenharmony_ci pluginData.set_tv_nsec(ts.tv_nsec); 8906f6ba60Sopenharmony_ci 9006f6ba60Sopenharmony_ci DoStats(pluginData.ByteSizeLong()); 9106f6ba60Sopenharmony_ci return shareMemoryBlock_->PutMessage(pluginData, pluginName_); 9206f6ba60Sopenharmony_ci} 9306f6ba60Sopenharmony_ci 9406f6ba60Sopenharmony_ciRandomWriteCtx* BufferWriter::StartReport() 9506f6ba60Sopenharmony_ci{ 9606f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr || writeCtx_ == nullptr) { 9706f6ba60Sopenharmony_ci return nullptr; 9806f6ba60Sopenharmony_ci } 9906f6ba60Sopenharmony_ci 10006f6ba60Sopenharmony_ci shareMemoryBlock_->ResetPos(); 10106f6ba60Sopenharmony_ci profilerPluginData_.Reset(writeCtx_); 10206f6ba60Sopenharmony_ci profilerPluginData_.set_name(pluginName_); 10306f6ba60Sopenharmony_ci profilerPluginData_.set_version(pluginVersion_); 10406f6ba60Sopenharmony_ci profilerPluginData_.set_status(0); 10506f6ba60Sopenharmony_ci return profilerPluginData_.startAdd_data(); 10606f6ba60Sopenharmony_ci} 10706f6ba60Sopenharmony_ci 10806f6ba60Sopenharmony_civoid BufferWriter::FinishReport(int32_t size) 10906f6ba60Sopenharmony_ci{ 11006f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr) { 11106f6ba60Sopenharmony_ci return; 11206f6ba60Sopenharmony_ci } 11306f6ba60Sopenharmony_ci 11406f6ba60Sopenharmony_ci profilerPluginData_.finishAdd_data(size); 11506f6ba60Sopenharmony_ci struct timespec ts; 11606f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &ts); 11706f6ba60Sopenharmony_ci profilerPluginData_.set_clock_id(ProfilerPluginData::CLOCKID_REALTIME); 11806f6ba60Sopenharmony_ci profilerPluginData_.set_tv_sec(ts.tv_sec); 11906f6ba60Sopenharmony_ci profilerPluginData_.set_tv_nsec(ts.tv_nsec); 12006f6ba60Sopenharmony_ci int32_t len = profilerPluginData_.Finish(); 12106f6ba60Sopenharmony_ci shareMemoryBlock_->UseMemory(len); 12206f6ba60Sopenharmony_ci DoStats(len); 12306f6ba60Sopenharmony_ci} 12406f6ba60Sopenharmony_ci 12506f6ba60Sopenharmony_cibool BufferWriter::WriteMessage(const google::protobuf::Message& pmsg, const std::string& pluginName) 12606f6ba60Sopenharmony_ci{ 12706f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr) { 12806f6ba60Sopenharmony_ci return false; 12906f6ba60Sopenharmony_ci } 13006f6ba60Sopenharmony_ci DoStats(pmsg.ByteSizeLong()); 13106f6ba60Sopenharmony_ci return shareMemoryBlock_->PutMessage(pmsg, pluginName); 13206f6ba60Sopenharmony_ci} 13306f6ba60Sopenharmony_ci 13406f6ba60Sopenharmony_cibool BufferWriter::Flush() 13506f6ba60Sopenharmony_ci{ 13606f6ba60Sopenharmony_ci ++flushCount_; 13706f6ba60Sopenharmony_ci if (eventNotifier_ == nullptr) { 13806f6ba60Sopenharmony_ci return false; 13906f6ba60Sopenharmony_ci } 14006f6ba60Sopenharmony_ci eventNotifier_->Post(flushCount_.load()); 14106f6ba60Sopenharmony_ci lastFlushTime_ = std::chrono::steady_clock::now(); 14206f6ba60Sopenharmony_ci bytesPending_ = 0; 14306f6ba60Sopenharmony_ci return true; 14406f6ba60Sopenharmony_ci} 14506f6ba60Sopenharmony_ci 14606f6ba60Sopenharmony_civoid BufferWriter::UseMemory(int32_t size) 14706f6ba60Sopenharmony_ci{ 14806f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr) { 14906f6ba60Sopenharmony_ci return; 15006f6ba60Sopenharmony_ci } 15106f6ba60Sopenharmony_ci 15206f6ba60Sopenharmony_ci shareMemoryBlock_->UseMemory(size); 15306f6ba60Sopenharmony_ci DoStats(size); 15406f6ba60Sopenharmony_ci} 15506f6ba60Sopenharmony_ci 15606f6ba60Sopenharmony_civoid BufferWriter::ResetPos() 15706f6ba60Sopenharmony_ci{ 15806f6ba60Sopenharmony_ci if (shareMemoryBlock_ == nullptr) { 15906f6ba60Sopenharmony_ci return; 16006f6ba60Sopenharmony_ci } 16106f6ba60Sopenharmony_ci 16206f6ba60Sopenharmony_ci shareMemoryBlock_->ResetPos(); 16306f6ba60Sopenharmony_ci}