1 // Copyright 2006 Google Inc. All Rights Reserved. 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 // pattern.h : global pattern references and initialization 16 17 // This file implements easy access to statically declared 18 // data patterns. 19 20 #ifndef STRESSAPPTEST_PATTERN_H_ 21 #define STRESSAPPTEST_PATTERN_H_ 22 23 #include <vector> 24 #include <string> 25 26 // This file must work with autoconf on its public version, 27 // so these includes are correct. 28 #include "adler32memcpy.h" 29 #include "sattypes.h" 30 31 // 2 = 128 bit bus, 1 = 64 bit bus, 0 = 32 bit bus 32 const int kBusShift = 2; 33 34 // Pattern and CRC data structure 35 struct PatternData { 36 const char *name; // Name of this pattern. 37 unsigned int *pat; // Data array. 38 unsigned int mask; // Size - 1. data[index & mask] is always valid. 39 unsigned char weight[4]; // Weighted frequency of this pattern. 40 // Each pattern has 32,64,128,256 width versions. 41 // All weights are added up, a random number is 42 // chosen between 0-sum(weights), and the 43 // appropriate pattern is chosen. Thus a weight of 44 // 1 is rare, a weight of 10 is 2x as likely to be 45 // chosen as a weight of 5. 46 }; 47 48 // Data structure to access data patterns. 49 class Pattern { 50 public: 51 Pattern(); 52 ~Pattern(); 53 // Fill pattern data and calculate CRC. 54 int Initialize(const struct PatternData &pattern_init, 55 int buswidth, 56 bool invert, 57 int weight); 58 59 // Access data members. 60 // "busshift_" allows for repeating each pattern word 1, 2, 4, etc. times. 61 // in order to create patterns of different width. 62 unsigned int pattern(unsigned int offset) { 63 unsigned int data = pattern_->pat[(offset >> busshift_) & pattern_->mask]; 64 if (inverse_) 65 data = ~data; 66 return data; 67 } 68 const AdlerChecksum *crc() {return crc_;} 69 unsigned int mask() {return pattern_->mask;} 70 unsigned int weight() {return weight_;} 71 const char *name() {return name_.c_str();} 72 73 private: 74 int CalculateCrc(); 75 const struct PatternData *pattern_; 76 int busshift_; // Target data bus width. 77 bool inverse_; // Invert the data from the original pattern. 78 AdlerChecksum *crc_; // CRC of this pattern. 79 string name_; // The human readable pattern name. 80 int weight_; // This is the likelihood that this 81 // pattern will be chosen. 82 // We want to copy this! 83 // DISALLOW_COPY_AND_ASSIGN(Pattern); 84 }; 85 86 // Object used to access global pattern list. 87 class PatternList { 88 public: 89 PatternList(); 90 ~PatternList(); 91 // Initialize pointers to global data patterns, and calculate CRC. 92 int Initialize(); 93 int Destroy(); 94 95 // Return the pattern designated by index i. 96 Pattern *GetPattern(int i); 97 // Return a random pattern according to the specified weighted probability. 98 Pattern *GetRandomPattern(); 99 // Return the number of patterns available. 100 int Size() {return size_;} 101 102 private: 103 vector<class Pattern> patterns_; 104 int weightcount_; // Total count of pattern weights. 105 unsigned int size_; 106 int initialized_; 107 DISALLOW_COPY_AND_ASSIGN(PatternList); 108 }; 109 110 // CrcIncrement allows an abstracted way to add a 32bit 111 // value into a running CRC. This function should be fast, and 112 // generate meaningful CRCs for the types of data patterns that 113 // we are using here. 114 // This CRC formula may not be optimal, but it does work. 115 // It may be improved in the future. 116 static inline uint32 CrcIncrement(uint32 crc, uint32 expected, int index) { 117 uint32 addition = (expected ^ index); 118 uint32 carry = (addition & crc) >> 31; 119 120 return crc + addition + carry; 121 } 122 123 124 #endif // STRESSAPPTEST_PATTERN_H_ 125