// Copyright 2008 Google Inc. All Rights Reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Interface for a thread-safe container of disk blocks #ifndef STRESSAPPTEST_DISK_BLOCKS_H_ #define STRESSAPPTEST_DISK_BLOCKS_H_ #include <sys/types.h> #include <pthread.h> #include <time.h> #include <sys/time.h> #include <errno.h> #include <map> #include <vector> #include <string> // This file must work with autoconf on its public version, // so these includes are correct. #include "pattern.h" // Data about a block written to disk so that it can be verified later. class BlockData { public: BlockData(); ~BlockData(); void SetParameters(int64 address, int64 size); void IncreaseReferenceCounter(); void DecreaseReferenceCounter(); int GetReferenceCounter(); void SetBlockAsInitialized(); bool BlockIsInitialized(); int64 GetAddress(); int64 GetSize(); void SetPattern(Pattern *p); Pattern *GetPattern(); protected: int64 addr_; // address of first sector in block int64 size_; // size of block int references_; // reference counter bool initialized_; // flag indicating the block was written on disk Pattern *pattern_; pthread_mutex_t data_mutex_; DISALLOW_COPY_AND_ASSIGN(BlockData); }; // Disk Block table - store data from blocks to be write / read by // a DiskThread class DiskBlockTable { public: DiskBlockTable(); virtual ~DiskBlockTable(); // Get Number of elements stored on table int64 NumElems(); // Clean all table data void CleanTable(); // Get a random block from the list. Only returns if a element // is available (consider that other thread must have added them. BlockData *GetRandomBlock(); // Set all initial parameters. Assumes all existent data is // invalid and, therefore, must be removed. void SetParameters(int sector_size, int write_block_size, int64 device_sectors, int64 segment_size, string device_name); // Return a new block in a unused address. BlockData *GetUnusedBlock(int64 segment); // Remove block from structure (called by write threads) int RemoveBlock(BlockData *block); // Release block to be erased (called by random threads) int ReleaseBlock(BlockData *block); protected: void InsertOnStructure(BlockData *block); // Generate a random 64-bit integer (virtual so it could be // override by the tests) virtual int64 Random64(); struct StorageData { BlockData *block; int pos; }; static const int kBlockRetry = 100; // Number of retries to allocate // sectors. typedef map<int64, StorageData*> AddrToBlockMap; typedef vector<int64> PosToAddrVector; PosToAddrVector pos_to_addr_; AddrToBlockMap addr_to_block_; uint64 nelems_; int sector_size_; // Sector size, in bytes int write_block_size_; // Block size, in bytes string device_name_; // Device name int64 device_sectors_; // Number of sectors in device int64 segment_size_; // Segment size, in bytes pthread_mutex_t data_mutex_; pthread_cond_t data_condition_; pthread_mutex_t parameter_mutex_; DISALLOW_COPY_AND_ASSIGN(DiskBlockTable); }; #endif // STRESSAPPTEST_BLOCKS_H_