xref: /aosp_15_r20/external/stressapptest/src/disk_blocks.h (revision 424fb153c814cbcb3e8904974796228774b3229a)
1*424fb153SAndroid Build Coastguard Worker // Copyright 2008 Google Inc. All Rights Reserved.
2*424fb153SAndroid Build Coastguard Worker 
3*424fb153SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*424fb153SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*424fb153SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*424fb153SAndroid Build Coastguard Worker 
7*424fb153SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
8*424fb153SAndroid Build Coastguard Worker 
9*424fb153SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*424fb153SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*424fb153SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*424fb153SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*424fb153SAndroid Build Coastguard Worker // limitations under the License.
14*424fb153SAndroid Build Coastguard Worker 
15*424fb153SAndroid Build Coastguard Worker // Interface for a thread-safe container of disk blocks
16*424fb153SAndroid Build Coastguard Worker 
17*424fb153SAndroid Build Coastguard Worker #ifndef STRESSAPPTEST_DISK_BLOCKS_H_
18*424fb153SAndroid Build Coastguard Worker #define STRESSAPPTEST_DISK_BLOCKS_H_
19*424fb153SAndroid Build Coastguard Worker 
20*424fb153SAndroid Build Coastguard Worker #include <sys/types.h>
21*424fb153SAndroid Build Coastguard Worker #include <pthread.h>
22*424fb153SAndroid Build Coastguard Worker #include <time.h>
23*424fb153SAndroid Build Coastguard Worker #include <sys/time.h>
24*424fb153SAndroid Build Coastguard Worker #include <errno.h>
25*424fb153SAndroid Build Coastguard Worker #include <map>
26*424fb153SAndroid Build Coastguard Worker #include <vector>
27*424fb153SAndroid Build Coastguard Worker #include <string>
28*424fb153SAndroid Build Coastguard Worker 
29*424fb153SAndroid Build Coastguard Worker #include "sattypes.h"
30*424fb153SAndroid Build Coastguard Worker 
31*424fb153SAndroid Build Coastguard Worker class Pattern;
32*424fb153SAndroid Build Coastguard Worker 
33*424fb153SAndroid Build Coastguard Worker // Data about a block written to disk so that it can be verified later.
34*424fb153SAndroid Build Coastguard Worker // Thread-unsafe, must be used with locks on non-const methods,
35*424fb153SAndroid Build Coastguard Worker // except for initialized accessor/mutator, which are thread-safe
36*424fb153SAndroid Build Coastguard Worker // (and in fact, is the only method supposed to be accessed from
37*424fb153SAndroid Build Coastguard Worker // someone which is not the thread-safe DiskBlockTable).
38*424fb153SAndroid Build Coastguard Worker class BlockData {
39*424fb153SAndroid Build Coastguard Worker  public:
40*424fb153SAndroid Build Coastguard Worker   BlockData();
41*424fb153SAndroid Build Coastguard Worker   ~BlockData();
42*424fb153SAndroid Build Coastguard Worker 
43*424fb153SAndroid Build Coastguard Worker   // These are reference counters used to control how many
44*424fb153SAndroid Build Coastguard Worker   // threads currently have a copy of this particular block.
IncreaseReferenceCounter()45*424fb153SAndroid Build Coastguard Worker   void IncreaseReferenceCounter() { references_++; }
DecreaseReferenceCounter()46*424fb153SAndroid Build Coastguard Worker   void DecreaseReferenceCounter() { references_--; }
GetReferenceCounter()47*424fb153SAndroid Build Coastguard Worker   int GetReferenceCounter() const { return references_; }
48*424fb153SAndroid Build Coastguard Worker 
49*424fb153SAndroid Build Coastguard Worker   // Controls whether the block was written on disk or not.
50*424fb153SAndroid Build Coastguard Worker   // Once written, you cannot "un-written" then without destroying
51*424fb153SAndroid Build Coastguard Worker   // this object.
52*424fb153SAndroid Build Coastguard Worker   void set_initialized();
53*424fb153SAndroid Build Coastguard Worker   bool initialized() const;
54*424fb153SAndroid Build Coastguard Worker 
55*424fb153SAndroid Build Coastguard Worker   // Accessor methods for some data related to blocks.
set_address(uint64 address)56*424fb153SAndroid Build Coastguard Worker   void set_address(uint64 address) { address_ = address; }
address()57*424fb153SAndroid Build Coastguard Worker   uint64 address() const { return address_; }
set_size(uint64 size)58*424fb153SAndroid Build Coastguard Worker   void set_size(uint64 size) { size_ = size; }
size()59*424fb153SAndroid Build Coastguard Worker   uint64 size() const { return size_; }
set_pattern(Pattern * p)60*424fb153SAndroid Build Coastguard Worker   void set_pattern(Pattern *p) { pattern_ = p; }
pattern()61*424fb153SAndroid Build Coastguard Worker   Pattern *pattern() { return pattern_; }
62*424fb153SAndroid Build Coastguard Worker  private:
63*424fb153SAndroid Build Coastguard Worker   uint64 address_;  // Address of first sector in block
64*424fb153SAndroid Build Coastguard Worker   uint64 size_;  // Size of block
65*424fb153SAndroid Build Coastguard Worker   int references_;  // Reference counter
66*424fb153SAndroid Build Coastguard Worker   bool initialized_;  // Flag indicating the block was written on disk
67*424fb153SAndroid Build Coastguard Worker   Pattern *pattern_;
68*424fb153SAndroid Build Coastguard Worker   mutable pthread_mutex_t data_mutex_;
69*424fb153SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(BlockData);
70*424fb153SAndroid Build Coastguard Worker };
71*424fb153SAndroid Build Coastguard Worker 
72*424fb153SAndroid Build Coastguard Worker // A thread-safe table used to store block data and control access
73*424fb153SAndroid Build Coastguard Worker // to these blocks, letting several threads read and write blocks on
74*424fb153SAndroid Build Coastguard Worker // disk.
75*424fb153SAndroid Build Coastguard Worker class DiskBlockTable {
76*424fb153SAndroid Build Coastguard Worker  public:
77*424fb153SAndroid Build Coastguard Worker   DiskBlockTable();
78*424fb153SAndroid Build Coastguard Worker   virtual ~DiskBlockTable();
79*424fb153SAndroid Build Coastguard Worker 
80*424fb153SAndroid Build Coastguard Worker   // Returns number of elements stored on table.
81*424fb153SAndroid Build Coastguard Worker   uint64 Size();
82*424fb153SAndroid Build Coastguard Worker 
83*424fb153SAndroid Build Coastguard Worker   // Sets all initial parameters. Assumes all existent data is
84*424fb153SAndroid Build Coastguard Worker   // invalid and, therefore, must be removed.
85*424fb153SAndroid Build Coastguard Worker   void SetParameters(int sector_size, int write_block_size,
86*424fb153SAndroid Build Coastguard Worker                      int64 device_sectors,
87*424fb153SAndroid Build Coastguard Worker                      int64 segment_size,
88*424fb153SAndroid Build Coastguard Worker                      const string& device_name);
89*424fb153SAndroid Build Coastguard Worker 
90*424fb153SAndroid Build Coastguard Worker   // During the regular execution, there will be 2 types of threads:
91*424fb153SAndroid Build Coastguard Worker   // - Write thread:  gets a large number of blocks using GetUnusedBlock,
92*424fb153SAndroid Build Coastguard Worker   //                  writes them on disk (if on destructive mode),
93*424fb153SAndroid Build Coastguard Worker   //                  reads block content ONCE from disk and them removes
94*424fb153SAndroid Build Coastguard Worker   //                  the block from queue with RemoveBlock. After a removal a
95*424fb153SAndroid Build Coastguard Worker   //                  block is not available for read threads, but it is
96*424fb153SAndroid Build Coastguard Worker   //                  only removed from memory if there is no reference for
97*424fb153SAndroid Build Coastguard Worker   //                  this block. Note that a write thread also counts as
98*424fb153SAndroid Build Coastguard Worker   //                  a reference.
99*424fb153SAndroid Build Coastguard Worker   // - Read threads:  get one block at a time (if available) with
100*424fb153SAndroid Build Coastguard Worker   //                  GetRandomBlock, reads its content from disk,
101*424fb153SAndroid Build Coastguard Worker   //                  checking whether it is correct or not, and releases
102*424fb153SAndroid Build Coastguard Worker   //                  (Using ReleaseBlock) the block to be erased by the
103*424fb153SAndroid Build Coastguard Worker   //                  write threads. Since several read threads are allowed
104*424fb153SAndroid Build Coastguard Worker   //                  to read the same block, a reference counter is used to
105*424fb153SAndroid Build Coastguard Worker   //                  control when the block can be REALLY erased from
106*424fb153SAndroid Build Coastguard Worker   //                  memory, and all memory management is made by a
107*424fb153SAndroid Build Coastguard Worker   //                  DiskBlockTable instance.
108*424fb153SAndroid Build Coastguard Worker 
109*424fb153SAndroid Build Coastguard Worker   // Returns a new block in a unused address. Does not
110*424fb153SAndroid Build Coastguard Worker   // grant ownership of the pointer to the caller
111*424fb153SAndroid Build Coastguard Worker   // (use RemoveBlock to delete the block from memory instead).
112*424fb153SAndroid Build Coastguard Worker   BlockData *GetUnusedBlock(int64 segment);
113*424fb153SAndroid Build Coastguard Worker 
114*424fb153SAndroid Build Coastguard Worker   // Removes block from structure (called by write threads). Returns
115*424fb153SAndroid Build Coastguard Worker   // 1 if successful, 0 otherwise.
116*424fb153SAndroid Build Coastguard Worker   int RemoveBlock(BlockData *block);
117*424fb153SAndroid Build Coastguard Worker 
118*424fb153SAndroid Build Coastguard Worker   // Gets a random block from the list. Only returns if an element
119*424fb153SAndroid Build Coastguard Worker   // is available (a write thread has got this block, written it on disk,
120*424fb153SAndroid Build Coastguard Worker   // and set this block as initialized). Does not grant ownership of the
121*424fb153SAndroid Build Coastguard Worker   // pointer to the caller (use RemoveBlock to delete the block from
122*424fb153SAndroid Build Coastguard Worker   // memory instead).
123*424fb153SAndroid Build Coastguard Worker   BlockData *GetRandomBlock();
124*424fb153SAndroid Build Coastguard Worker 
125*424fb153SAndroid Build Coastguard Worker   // Releases block to be erased (called by random threads). Returns
126*424fb153SAndroid Build Coastguard Worker   // 1 if successful, 0 otherwise.
127*424fb153SAndroid Build Coastguard Worker   int ReleaseBlock(BlockData *block);
128*424fb153SAndroid Build Coastguard Worker 
129*424fb153SAndroid Build Coastguard Worker  protected:
130*424fb153SAndroid Build Coastguard Worker   struct StorageData {
131*424fb153SAndroid Build Coastguard Worker     BlockData *block;
132*424fb153SAndroid Build Coastguard Worker     int pos;
133*424fb153SAndroid Build Coastguard Worker   };
134*424fb153SAndroid Build Coastguard Worker   typedef map<int64, StorageData*> AddrToBlockMap;
135*424fb153SAndroid Build Coastguard Worker   typedef vector<int64> PosToAddrVector;
136*424fb153SAndroid Build Coastguard Worker 
137*424fb153SAndroid Build Coastguard Worker   // Inserts block in structure, used in tests and by other methods.
138*424fb153SAndroid Build Coastguard Worker   void InsertOnStructure(BlockData *block);
139*424fb153SAndroid Build Coastguard Worker 
140*424fb153SAndroid Build Coastguard Worker   // Generates a random 64-bit integer.
141*424fb153SAndroid Build Coastguard Worker   // Virtual method so it can be overridden by the tests.
142*424fb153SAndroid Build Coastguard Worker   virtual int64 Random64();
143*424fb153SAndroid Build Coastguard Worker 
144*424fb153SAndroid Build Coastguard Worker   // Accessor methods for testing.
pos_to_addr()145*424fb153SAndroid Build Coastguard Worker   const PosToAddrVector& pos_to_addr() const { return pos_to_addr_; }
addr_to_block()146*424fb153SAndroid Build Coastguard Worker   const AddrToBlockMap& addr_to_block() const { return addr_to_block_; }
147*424fb153SAndroid Build Coastguard Worker 
sector_size()148*424fb153SAndroid Build Coastguard Worker   int sector_size() const { return sector_size_; }
write_block_size()149*424fb153SAndroid Build Coastguard Worker   int write_block_size() const { return write_block_size_; }
device_name()150*424fb153SAndroid Build Coastguard Worker   const string& device_name() const { return device_name_; }
device_sectors()151*424fb153SAndroid Build Coastguard Worker   int64 device_sectors() const { return device_sectors_; }
segment_size()152*424fb153SAndroid Build Coastguard Worker   int64 segment_size() const { return segment_size_; }
153*424fb153SAndroid Build Coastguard Worker 
154*424fb153SAndroid Build Coastguard Worker  private:
155*424fb153SAndroid Build Coastguard Worker   // Number of retries to allocate sectors.
156*424fb153SAndroid Build Coastguard Worker   static const int kBlockRetry = 100;
157*424fb153SAndroid Build Coastguard Worker   // Actual tables.
158*424fb153SAndroid Build Coastguard Worker   PosToAddrVector pos_to_addr_;
159*424fb153SAndroid Build Coastguard Worker   AddrToBlockMap addr_to_block_;
160*424fb153SAndroid Build Coastguard Worker 
161*424fb153SAndroid Build Coastguard Worker   // Configuration parameters for block selection
162*424fb153SAndroid Build Coastguard Worker   int sector_size_;  // Sector size, in bytes
163*424fb153SAndroid Build Coastguard Worker   int write_block_size_;  // Block size, in bytes
164*424fb153SAndroid Build Coastguard Worker   string device_name_;  // Device name
165*424fb153SAndroid Build Coastguard Worker   int64 device_sectors_;  // Number of sectors in device
166*424fb153SAndroid Build Coastguard Worker   int64 segment_size_;  // Segment size in bytes
167*424fb153SAndroid Build Coastguard Worker   uint64 size_;  // Number of elements on table
168*424fb153SAndroid Build Coastguard Worker   pthread_mutex_t data_mutex_;
169*424fb153SAndroid Build Coastguard Worker   pthread_cond_t data_condition_;
170*424fb153SAndroid Build Coastguard Worker   pthread_mutex_t parameter_mutex_;
171*424fb153SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(DiskBlockTable);
172*424fb153SAndroid Build Coastguard Worker };
173*424fb153SAndroid Build Coastguard Worker 
174*424fb153SAndroid Build Coastguard Worker #endif  // STRESSAPPTEST_BLOCKS_H_
175