xref: /aosp_15_r20/test/dittosuite/src/read_write_file.cpp (revision 6fa2df46f119dce7527f5beb2814eca0e6f886ac)
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/read_write_file.h>
16*6fa2df46SAndroid Build Coastguard Worker 
17*6fa2df46SAndroid Build Coastguard Worker #include <ditto/logger.h>
18*6fa2df46SAndroid Build Coastguard Worker #include <ditto/shared_variables.h>
19*6fa2df46SAndroid Build Coastguard Worker 
20*6fa2df46SAndroid Build Coastguard Worker #include <ditto/utils.h>
21*6fa2df46SAndroid Build Coastguard Worker 
22*6fa2df46SAndroid Build Coastguard Worker namespace dittosuite {
23*6fa2df46SAndroid Build Coastguard Worker 
ReadWriteFile(const std::string & name,const Params & params,int64_t size,int64_t block_size,int64_t starting_offset,Order access_order,uint32_t seed,Reseeding reseeding,int input_fd_key)24*6fa2df46SAndroid Build Coastguard Worker ReadWriteFile::ReadWriteFile(const std::string& name, const Params& params, int64_t size,
25*6fa2df46SAndroid Build Coastguard Worker                              int64_t block_size, int64_t starting_offset, Order access_order,
26*6fa2df46SAndroid Build Coastguard Worker                              uint32_t seed, Reseeding reseeding, int input_fd_key)
27*6fa2df46SAndroid Build Coastguard Worker     : Instruction(name, params),
28*6fa2df46SAndroid Build Coastguard Worker       size_(size),
29*6fa2df46SAndroid Build Coastguard Worker       block_size_(block_size),
30*6fa2df46SAndroid Build Coastguard Worker       starting_offset_(starting_offset),
31*6fa2df46SAndroid Build Coastguard Worker       access_order_(access_order),
32*6fa2df46SAndroid Build Coastguard Worker       gen_(seed),
33*6fa2df46SAndroid Build Coastguard Worker       seed_(seed),
34*6fa2df46SAndroid Build Coastguard Worker       reseeding_(reseeding),
35*6fa2df46SAndroid Build Coastguard Worker       input_fd_key_(input_fd_key),
36*6fa2df46SAndroid Build Coastguard Worker       update_size_(size == -1),
37*6fa2df46SAndroid Build Coastguard Worker       update_block_size_(block_size == -1) {
38*6fa2df46SAndroid Build Coastguard Worker   if (access_order == Order::kRandom && starting_offset != 0) {
39*6fa2df46SAndroid Build Coastguard Worker     LOGE(
40*6fa2df46SAndroid Build Coastguard Worker         "Starting offset is not 0, although the chosen access_order is RANDOM. Starting offset "
41*6fa2df46SAndroid Build Coastguard Worker         "will be "
42*6fa2df46SAndroid Build Coastguard Worker         "ignored");
43*6fa2df46SAndroid Build Coastguard Worker   }
44*6fa2df46SAndroid Build Coastguard Worker }
45*6fa2df46SAndroid Build Coastguard Worker 
CollectResults(const std::string & prefix)46*6fa2df46SAndroid Build Coastguard Worker std::unique_ptr<Result> ReadWriteFile::CollectResults(const std::string& prefix) {
47*6fa2df46SAndroid Build Coastguard Worker   auto result = Instruction::CollectResults(prefix);
48*6fa2df46SAndroid Build Coastguard Worker   result->AddMeasurement("bandwidth", bandwidth_sampler_.GetSamples());
49*6fa2df46SAndroid Build Coastguard Worker   return result;
50*6fa2df46SAndroid Build Coastguard Worker }
51*6fa2df46SAndroid Build Coastguard Worker 
SetUp()52*6fa2df46SAndroid Build Coastguard Worker void ReadWriteFile::SetUp() {
53*6fa2df46SAndroid Build Coastguard Worker   if (reseeding_ == Reseeding::kEachRoundOfCycles) {
54*6fa2df46SAndroid Build Coastguard Worker     gen_.seed(seed_);
55*6fa2df46SAndroid Build Coastguard Worker   }
56*6fa2df46SAndroid Build Coastguard Worker }
57*6fa2df46SAndroid Build Coastguard Worker 
SetUpSingle()58*6fa2df46SAndroid Build Coastguard Worker void ReadWriteFile::SetUpSingle() {
59*6fa2df46SAndroid Build Coastguard Worker   int fd = std::get<int>(SharedVariables::Get(input_fd_key_));
60*6fa2df46SAndroid Build Coastguard Worker   int64_t file_size = GetFileSize(syscall_, fd);
61*6fa2df46SAndroid Build Coastguard Worker 
62*6fa2df46SAndroid Build Coastguard Worker   if (update_size_) {
63*6fa2df46SAndroid Build Coastguard Worker     size_ = file_size;
64*6fa2df46SAndroid Build Coastguard Worker   }
65*6fa2df46SAndroid Build Coastguard Worker   if (update_block_size_) {
66*6fa2df46SAndroid Build Coastguard Worker     block_size_ = file_size;
67*6fa2df46SAndroid Build Coastguard Worker   }
68*6fa2df46SAndroid Build Coastguard Worker 
69*6fa2df46SAndroid Build Coastguard Worker   if (block_size_ > file_size) {
70*6fa2df46SAndroid Build Coastguard Worker     LOGF("Supplied block_size (" + std::to_string(block_size_) +
71*6fa2df46SAndroid Build Coastguard Worker          ") is greater than total file size (" + std::to_string(file_size) +
72*6fa2df46SAndroid Build Coastguard Worker          "). File path:" + GetFilePath(syscall_, fd));
73*6fa2df46SAndroid Build Coastguard Worker   }
74*6fa2df46SAndroid Build Coastguard Worker 
75*6fa2df46SAndroid Build Coastguard Worker   buffer_ = std::unique_ptr<char[]>(new (std::nothrow) char[block_size_]);
76*6fa2df46SAndroid Build Coastguard Worker   if (buffer_ == nullptr) {
77*6fa2df46SAndroid Build Coastguard Worker     PLOGF("Error while allocating buffer for Read/Write");
78*6fa2df46SAndroid Build Coastguard Worker   }
79*6fa2df46SAndroid Build Coastguard Worker   std::fill(buffer_.get(), buffer_.get() + block_size_, 170);  // 170 = 10101010
80*6fa2df46SAndroid Build Coastguard Worker 
81*6fa2df46SAndroid Build Coastguard Worker   if (reseeding_ == Reseeding::kEachCycle) {
82*6fa2df46SAndroid Build Coastguard Worker     gen_.seed(seed_);
83*6fa2df46SAndroid Build Coastguard Worker   }
84*6fa2df46SAndroid Build Coastguard Worker 
85*6fa2df46SAndroid Build Coastguard Worker   units_.clear();
86*6fa2df46SAndroid Build Coastguard Worker 
87*6fa2df46SAndroid Build Coastguard Worker   switch (access_order_) {
88*6fa2df46SAndroid Build Coastguard Worker     case Order::kSequential: {
89*6fa2df46SAndroid Build Coastguard Worker       int64_t offset = starting_offset_;
90*6fa2df46SAndroid Build Coastguard Worker       for (int64_t i = 0; i < (size_ / block_size_); i++) {
91*6fa2df46SAndroid Build Coastguard Worker         if (offset > file_size - block_size_) {
92*6fa2df46SAndroid Build Coastguard Worker           offset = 0;
93*6fa2df46SAndroid Build Coastguard Worker         }
94*6fa2df46SAndroid Build Coastguard Worker         units_.push_back({block_size_, offset});
95*6fa2df46SAndroid Build Coastguard Worker         offset += block_size_;
96*6fa2df46SAndroid Build Coastguard Worker       }
97*6fa2df46SAndroid Build Coastguard Worker       break;
98*6fa2df46SAndroid Build Coastguard Worker     }
99*6fa2df46SAndroid Build Coastguard Worker     case Order::kRandom: {
100*6fa2df46SAndroid Build Coastguard Worker       std::uniform_int_distribution<> uniform_distribution(0, file_size - block_size_);
101*6fa2df46SAndroid Build Coastguard Worker 
102*6fa2df46SAndroid Build Coastguard Worker       for (int64_t i = 0; i < (size_ / block_size_); i++) {
103*6fa2df46SAndroid Build Coastguard Worker         units_.push_back({block_size_, uniform_distribution(gen_)});
104*6fa2df46SAndroid Build Coastguard Worker       }
105*6fa2df46SAndroid Build Coastguard Worker       break;
106*6fa2df46SAndroid Build Coastguard Worker     }
107*6fa2df46SAndroid Build Coastguard Worker   }
108*6fa2df46SAndroid Build Coastguard Worker 
109*6fa2df46SAndroid Build Coastguard Worker   Instruction::SetUpSingle();
110*6fa2df46SAndroid Build Coastguard Worker }
111*6fa2df46SAndroid Build Coastguard Worker 
RunSingle()112*6fa2df46SAndroid Build Coastguard Worker void ReadWriteFile::RunSingle() {}
113*6fa2df46SAndroid Build Coastguard Worker 
WriteFile(const Params & params,int64_t size,int64_t block_size,int64_t starting_offset,Order access_order,uint32_t seed,Reseeding reseeding,bool fsync,int input_fd_key)114*6fa2df46SAndroid Build Coastguard Worker WriteFile::WriteFile(const Params& params, int64_t size, int64_t block_size,
115*6fa2df46SAndroid Build Coastguard Worker                      int64_t starting_offset, Order access_order, uint32_t seed,
116*6fa2df46SAndroid Build Coastguard Worker                      Reseeding reseeding, bool fsync, int input_fd_key)
117*6fa2df46SAndroid Build Coastguard Worker     : ReadWriteFile(kName, params, size, block_size, starting_offset, access_order, seed, reseeding,
118*6fa2df46SAndroid Build Coastguard Worker                     input_fd_key),
119*6fa2df46SAndroid Build Coastguard Worker       fsync_(fsync) {}
120*6fa2df46SAndroid Build Coastguard Worker 
RunSingle()121*6fa2df46SAndroid Build Coastguard Worker void WriteFile::RunSingle() {
122*6fa2df46SAndroid Build Coastguard Worker   int fd = std::get<int>(SharedVariables::Get(input_fd_key_));
123*6fa2df46SAndroid Build Coastguard Worker 
124*6fa2df46SAndroid Build Coastguard Worker   for (const auto& unit : units_) {
125*6fa2df46SAndroid Build Coastguard Worker     if (syscall_.Write(fd, buffer_.get(), unit.count, unit.offset) == -1) {
126*6fa2df46SAndroid Build Coastguard Worker       LOGF("Error while calling write()");
127*6fa2df46SAndroid Build Coastguard Worker     }
128*6fa2df46SAndroid Build Coastguard Worker   }
129*6fa2df46SAndroid Build Coastguard Worker 
130*6fa2df46SAndroid Build Coastguard Worker   if (fsync_ && syscall_.FSync(fd) != 0) {
131*6fa2df46SAndroid Build Coastguard Worker     LOGF("Error while calling fsync()");
132*6fa2df46SAndroid Build Coastguard Worker   }
133*6fa2df46SAndroid Build Coastguard Worker }
134*6fa2df46SAndroid Build Coastguard Worker 
ReadFile(const Params & params,int64_t size,int64_t block_size,int64_t starting_offset,Order access_order,uint32_t seed,Reseeding reseeding,int fadvise,int input_fd_key)135*6fa2df46SAndroid Build Coastguard Worker ReadFile::ReadFile(const Params& params, int64_t size, int64_t block_size, int64_t starting_offset,
136*6fa2df46SAndroid Build Coastguard Worker                    Order access_order, uint32_t seed, Reseeding reseeding, int fadvise,
137*6fa2df46SAndroid Build Coastguard Worker                    int input_fd_key)
138*6fa2df46SAndroid Build Coastguard Worker     : ReadWriteFile(kName, params, size, block_size, starting_offset, access_order, seed, reseeding,
139*6fa2df46SAndroid Build Coastguard Worker                     input_fd_key),
140*6fa2df46SAndroid Build Coastguard Worker       fadvise_(fadvise) {}
141*6fa2df46SAndroid Build Coastguard Worker 
SetUpSingle()142*6fa2df46SAndroid Build Coastguard Worker void ReadFile::SetUpSingle() {
143*6fa2df46SAndroid Build Coastguard Worker   int fd = std::get<int>(SharedVariables::Get(input_fd_key_));
144*6fa2df46SAndroid Build Coastguard Worker   int64_t file_size = GetFileSize(syscall_, fd);
145*6fa2df46SAndroid Build Coastguard Worker 
146*6fa2df46SAndroid Build Coastguard Worker   if (syscall_.FAdvise(fd, 0, file_size, fadvise_) != 0) {
147*6fa2df46SAndroid Build Coastguard Worker     LOGF("Error while calling fadvise()");
148*6fa2df46SAndroid Build Coastguard Worker   }
149*6fa2df46SAndroid Build Coastguard Worker   ReadWriteFile::SetUpSingle();
150*6fa2df46SAndroid Build Coastguard Worker }
151*6fa2df46SAndroid Build Coastguard Worker 
RunSingle()152*6fa2df46SAndroid Build Coastguard Worker void ReadFile::RunSingle() {
153*6fa2df46SAndroid Build Coastguard Worker   int fd = std::get<int>(SharedVariables::Get(input_fd_key_));
154*6fa2df46SAndroid Build Coastguard Worker 
155*6fa2df46SAndroid Build Coastguard Worker   for (const auto& unit : units_) {
156*6fa2df46SAndroid Build Coastguard Worker     if (syscall_.Read(fd, buffer_.get(), unit.count, unit.offset) == -1) {
157*6fa2df46SAndroid Build Coastguard Worker       LOGF("Error while calling read()");
158*6fa2df46SAndroid Build Coastguard Worker     }
159*6fa2df46SAndroid Build Coastguard Worker   }
160*6fa2df46SAndroid Build Coastguard Worker }
161*6fa2df46SAndroid Build Coastguard Worker 
TearDownSingle(bool is_last)162*6fa2df46SAndroid Build Coastguard Worker void ReadWriteFile::TearDownSingle(bool is_last) {
163*6fa2df46SAndroid Build Coastguard Worker   Instruction::TearDownSingle(is_last);
164*6fa2df46SAndroid Build Coastguard Worker   bandwidth_sampler_.Measure(size_, time_sampler_.GetSamples().back());
165*6fa2df46SAndroid Build Coastguard Worker }
166*6fa2df46SAndroid Build Coastguard Worker 
167*6fa2df46SAndroid Build Coastguard Worker }  // namespace dittosuite
168