1b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Copyright 2008 Google Inc. All Rights Reserved. 2b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 3b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Licensed under the Apache License, Version 2.0 (the "License"); 4b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// you may not use this file except in compliance with the License. 5b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// You may obtain a copy of the License at 6b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 7b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// http://www.apache.org/licenses/LICENSE-2.0 8b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 9b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Unless required by applicable law or agreed to in writing, software 10b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// distributed under the License is distributed on an "AS IS" BASIS, 11b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// See the License for the specific language governing permissions and 13b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// limitations under the License. 14b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 15b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Interface for a thread-safe container of disk blocks 16b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 17b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#ifndef STRESSAPPTEST_DISK_BLOCKS_H_ 18b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define STRESSAPPTEST_DISK_BLOCKS_H_ 19b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 20b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <sys/types.h> 21b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <pthread.h> 22b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <time.h> 23b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <sys/time.h> 24b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <errno.h> 25b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <map> 26b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <vector> 27b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <string> 28b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This file must work with autoconf on its public version, 29b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// so these includes are correct. 30b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "pattern.h" 31b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 32b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Data about a block written to disk so that it can be verified later. 33b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass BlockData { 34b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 35b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson BlockData(); 36b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ~BlockData(); 37b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetParameters(int64 address, int64 size); 38b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void IncreaseReferenceCounter(); 39b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void DecreaseReferenceCounter(); 40b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int GetReferenceCounter(); 41b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetBlockAsInitialized(); 42b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool BlockIsInitialized(); 43b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetAddress(); 44b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetSize(); 45b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetPattern(Pattern *p); 46b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Pattern *GetPattern(); 47b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 48b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 addr_; // address of first sector in block 49b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 size_; // size of block 50b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int references_; // reference counter 51b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool initialized_; // flag indicating the block was written on disk 52b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Pattern *pattern_; 53b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_mutex_t data_mutex_; 54b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(BlockData); 55b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 56b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 57b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Disk Block table - store data from blocks to be write / read by 58b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// a DiskThread 59b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass DiskBlockTable { 60b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 61b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskBlockTable(); 62b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~DiskBlockTable(); 63b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 64b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get Number of elements stored on table 65b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 NumElems(); 66b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Clean all table data 67b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void CleanTable(); 68b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get a random block from the list. Only returns if a element 69b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // is available (consider that other thread must have added them. 70b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson BlockData *GetRandomBlock(); 71b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set all initial parameters. Assumes all existent data is 72b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // invalid and, therefore, must be removed. 73b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetParameters(int sector_size, int write_block_size, 74b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 device_sectors, 75b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 segment_size, 76b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string device_name); 77b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Return a new block in a unused address. 78b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson BlockData *GetUnusedBlock(int64 segment); 79b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Remove block from structure (called by write threads) 80b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int RemoveBlock(BlockData *block); 81b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Release block to be erased (called by random threads) 82b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int ReleaseBlock(BlockData *block); 83b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 84b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 85b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 86b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void InsertOnStructure(BlockData *block); 87b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Generate a random 64-bit integer (virtual so it could be 88b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // override by the tests) 89b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int64 Random64(); 90b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 91b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct StorageData { 92b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson BlockData *block; 93b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int pos; 94b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 95b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 96b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kBlockRetry = 100; // Number of retries to allocate 97b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // sectors. 98b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 99b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson typedef map<int64, StorageData*> AddrToBlockMap; 100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson typedef vector<int64> PosToAddrVector; 101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PosToAddrVector pos_to_addr_; 102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrToBlockMap addr_to_block_; 103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 nelems_; 104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int sector_size_; // Sector size, in bytes 105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int write_block_size_; // Block size, in bytes 106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string device_name_; // Device name 107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 device_sectors_; // Number of sectors in device 108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 segment_size_; // Segment size, in bytes 109b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_mutex_t data_mutex_; 110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_cond_t data_condition_; 111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_mutex_t parameter_mutex_; 112b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(DiskBlockTable); 113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif // STRESSAPPTEST_BLOCKS_H_ 116