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