1*6fa2df46SAndroid Build Coastguard Worker // Copyright (C) 2021 The Android Open Source Project
2*6fa2df46SAndroid Build Coastguard Worker //
3*6fa2df46SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*6fa2df46SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*6fa2df46SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*6fa2df46SAndroid Build Coastguard Worker //
7*6fa2df46SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*6fa2df46SAndroid Build Coastguard Worker //
9*6fa2df46SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*6fa2df46SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*6fa2df46SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6fa2df46SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*6fa2df46SAndroid Build Coastguard Worker // limitations under the License.
14*6fa2df46SAndroid Build Coastguard Worker
15*6fa2df46SAndroid Build Coastguard Worker #include <ditto/parser.h>
16*6fa2df46SAndroid Build Coastguard Worker
17*6fa2df46SAndroid Build Coastguard Worker #include <fcntl.h>
18*6fa2df46SAndroid Build Coastguard Worker
19*6fa2df46SAndroid Build Coastguard Worker #include <cstdlib>
20*6fa2df46SAndroid Build Coastguard Worker #include <fstream>
21*6fa2df46SAndroid Build Coastguard Worker
22*6fa2df46SAndroid Build Coastguard Worker #include <ditto/embedded_benchmarks.h>
23*6fa2df46SAndroid Build Coastguard Worker #include <ditto/instruction_factory.h>
24*6fa2df46SAndroid Build Coastguard Worker #include <ditto/logger.h>
25*6fa2df46SAndroid Build Coastguard Worker #include <ditto/shared_variables.h>
26*6fa2df46SAndroid Build Coastguard Worker
27*6fa2df46SAndroid Build Coastguard Worker #include <google/protobuf/text_format.h>
28*6fa2df46SAndroid Build Coastguard Worker
29*6fa2df46SAndroid Build Coastguard Worker namespace dittosuite {
30*6fa2df46SAndroid Build Coastguard Worker
GetParser()31*6fa2df46SAndroid Build Coastguard Worker Parser& Parser::GetParser() {
32*6fa2df46SAndroid Build Coastguard Worker static Parser parser;
33*6fa2df46SAndroid Build Coastguard Worker return parser;
34*6fa2df46SAndroid Build Coastguard Worker }
35*6fa2df46SAndroid Build Coastguard Worker
__Parse(std::string json_benchmark,const std::vector<std::string> & parameters)36*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<dittosuiteproto::Benchmark> Parser::__Parse(
37*6fa2df46SAndroid Build Coastguard Worker std::string json_benchmark, const std::vector<std::string>& parameters)
38*6fa2df46SAndroid Build Coastguard Worker
39*6fa2df46SAndroid Build Coastguard Worker {
40*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<dittosuiteproto::Benchmark> benchmark =
41*6fa2df46SAndroid Build Coastguard Worker std::make_unique<dittosuiteproto::Benchmark>();
42*6fa2df46SAndroid Build Coastguard Worker
43*6fa2df46SAndroid Build Coastguard Worker for (std::size_t i = 0; i < parameters.size(); i++) {
44*6fa2df46SAndroid Build Coastguard Worker std::string to_replace("$PARAMETER_" + std::to_string(i + 1) + "$");
45*6fa2df46SAndroid Build Coastguard Worker auto position = json_benchmark.find(to_replace);
46*6fa2df46SAndroid Build Coastguard Worker if (position == std::string::npos) {
47*6fa2df46SAndroid Build Coastguard Worker LOGW(to_replace + " does not exist in .ditto file");
48*6fa2df46SAndroid Build Coastguard Worker continue;
49*6fa2df46SAndroid Build Coastguard Worker }
50*6fa2df46SAndroid Build Coastguard Worker json_benchmark.replace(position, to_replace.size(), parameters[i]);
51*6fa2df46SAndroid Build Coastguard Worker }
52*6fa2df46SAndroid Build Coastguard Worker
53*6fa2df46SAndroid Build Coastguard Worker if (!google::protobuf::TextFormat::ParseFromString(json_benchmark, benchmark.get())) {
54*6fa2df46SAndroid Build Coastguard Worker LOGF("Error while parsing .ditto file");
55*6fa2df46SAndroid Build Coastguard Worker }
56*6fa2df46SAndroid Build Coastguard Worker
57*6fa2df46SAndroid Build Coastguard Worker std::list<int> thread_ids({InstructionFactory::GenerateThreadId()});
58*6fa2df46SAndroid Build Coastguard Worker auto absolute_path_key = SharedVariables::GetKey(thread_ids, "absolute_path");
59*6fa2df46SAndroid Build Coastguard Worker SharedVariables::Set(absolute_path_key, benchmark->global().absolute_path());
60*6fa2df46SAndroid Build Coastguard Worker Instruction::SetAbsolutePathKey(absolute_path_key);
61*6fa2df46SAndroid Build Coastguard Worker
62*6fa2df46SAndroid Build Coastguard Worker if (benchmark->global().has_mutex()) {
63*6fa2df46SAndroid Build Coastguard Worker pthread_mutex_t mux_orig;
64*6fa2df46SAndroid Build Coastguard Worker
65*6fa2df46SAndroid Build Coastguard Worker auto mutex_key = SharedVariables::GetKey(thread_ids, benchmark->global().mutex().name());
66*6fa2df46SAndroid Build Coastguard Worker SharedVariables::Set(mutex_key, mux_orig);
67*6fa2df46SAndroid Build Coastguard Worker pthread_mutex_t* mux = std::get_if<pthread_mutex_t>(SharedVariables::GetPointer(mutex_key));
68*6fa2df46SAndroid Build Coastguard Worker pthread_mutex_init(mux, nullptr);
69*6fa2df46SAndroid Build Coastguard Worker }
70*6fa2df46SAndroid Build Coastguard Worker
71*6fa2df46SAndroid Build Coastguard Worker if (benchmark->has_init()) {
72*6fa2df46SAndroid Build Coastguard Worker init_ = InstructionFactory::CreateFromProtoInstruction(thread_ids, benchmark->init());
73*6fa2df46SAndroid Build Coastguard Worker }
74*6fa2df46SAndroid Build Coastguard Worker main_ = InstructionFactory::CreateFromProtoInstruction(thread_ids, benchmark->main());
75*6fa2df46SAndroid Build Coastguard Worker if (benchmark->has_clean_up()) {
76*6fa2df46SAndroid Build Coastguard Worker clean_up_ = InstructionFactory::CreateFromProtoInstruction(thread_ids, benchmark->clean_up());
77*6fa2df46SAndroid Build Coastguard Worker }
78*6fa2df46SAndroid Build Coastguard Worker
79*6fa2df46SAndroid Build Coastguard Worker SharedVariables::ClearKeys();
80*6fa2df46SAndroid Build Coastguard Worker
81*6fa2df46SAndroid Build Coastguard Worker return benchmark;
82*6fa2df46SAndroid Build Coastguard Worker }
83*6fa2df46SAndroid Build Coastguard Worker
ParseEmbedded(const std::string & embedded_benchmark,const std::vector<std::string> & parameters)84*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<dittosuiteproto::Benchmark> Parser::ParseEmbedded(
85*6fa2df46SAndroid Build Coastguard Worker const std::string& embedded_benchmark, const std::vector<std::string>& parameters) {
86*6fa2df46SAndroid Build Coastguard Worker auto json_benchmark_it = ditto_static_config.find(embedded_benchmark);
87*6fa2df46SAndroid Build Coastguard Worker if (json_benchmark_it == ditto_static_config.end()) {
88*6fa2df46SAndroid Build Coastguard Worker LOGF("The requested benchmark is invalid: " + embedded_benchmark);
89*6fa2df46SAndroid Build Coastguard Worker }
90*6fa2df46SAndroid Build Coastguard Worker
91*6fa2df46SAndroid Build Coastguard Worker return __Parse(json_benchmark_it->second, parameters);
92*6fa2df46SAndroid Build Coastguard Worker }
93*6fa2df46SAndroid Build Coastguard Worker
ParseFile(const std::string & file_path,const std::vector<std::string> & parameters)94*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<dittosuiteproto::Benchmark> Parser::ParseFile(
95*6fa2df46SAndroid Build Coastguard Worker const std::string& file_path, const std::vector<std::string>& parameters) {
96*6fa2df46SAndroid Build Coastguard Worker std::ifstream file(file_path);
97*6fa2df46SAndroid Build Coastguard Worker if (!file.is_open()) {
98*6fa2df46SAndroid Build Coastguard Worker LOGF("Provided .ditto file was not found: " + file_path);
99*6fa2df46SAndroid Build Coastguard Worker }
100*6fa2df46SAndroid Build Coastguard Worker
101*6fa2df46SAndroid Build Coastguard Worker std::string json_benchmark((std::istreambuf_iterator<char>(file)),
102*6fa2df46SAndroid Build Coastguard Worker (std::istreambuf_iterator<char>()));
103*6fa2df46SAndroid Build Coastguard Worker
104*6fa2df46SAndroid Build Coastguard Worker return __Parse(json_benchmark, parameters);
105*6fa2df46SAndroid Build Coastguard Worker }
106*6fa2df46SAndroid Build Coastguard Worker
GetInit()107*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<Instruction> Parser::GetInit() {
108*6fa2df46SAndroid Build Coastguard Worker return std::move(init_);
109*6fa2df46SAndroid Build Coastguard Worker }
110*6fa2df46SAndroid Build Coastguard Worker
GetMain()111*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<Instruction> Parser::GetMain() {
112*6fa2df46SAndroid Build Coastguard Worker return std::move(main_);
113*6fa2df46SAndroid Build Coastguard Worker }
114*6fa2df46SAndroid Build Coastguard Worker
GetCleanUp()115*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<Instruction> Parser::GetCleanUp() {
116*6fa2df46SAndroid Build Coastguard Worker return std::move(clean_up_);
117*6fa2df46SAndroid Build Coastguard Worker }
118*6fa2df46SAndroid Build Coastguard Worker
119*6fa2df46SAndroid Build Coastguard Worker } // namespace dittosuite
120