| // Copyright 2006 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. |
| |
| // pattern.h : global pattern references and initialization |
| |
| // This file implements easy access to statically declared |
| // data patterns. |
| |
| #ifndef STRESSAPPTEST_PATTERN_H_ |
| #define STRESSAPPTEST_PATTERN_H_ |
| |
| #include <vector> |
| #include <string> |
| |
| // This file must work with autoconf on its public version, |
| // so these includes are correct. |
| #include "adler32memcpy.h" |
| #include "sattypes.h" |
| |
| // 2 = 128 bit bus, 1 = 64 bit bus, 0 = 32 bit bus |
| const int kBusShift = 2; |
| |
| // Pattern and CRC data structure |
| struct PatternData { |
| const char *name; // Name of this pattern. |
| unsigned int *pat; // Data array. |
| unsigned int mask; // Size - 1. data[index & mask] is always valid. |
| unsigned char weight[4]; // Weighted frequency of this pattern. |
| // Each pattern has 32,64,128,256 width versions. |
| // All weights are added up, a random number is |
| // chosen between 0-sum(weights), and the |
| // appropriate pattern is chosen. Thus a weight of |
| // 1 is rare, a weight of 10 is 2x as likely to be |
| // chosen as a weight of 5. |
| }; |
| |
| // Data structure to access data patterns. |
| class Pattern { |
| public: |
| Pattern(); |
| ~Pattern(); |
| // Fill pattern data and calculate CRC. |
| int Initialize(const struct PatternData &pattern_init, |
| int buswidth, |
| bool invert, |
| int weight); |
| |
| // Access data members. |
| // "busshift_" allows for repeating each pattern word 1, 2, 4, etc. times. |
| // in order to create patterns of different width. |
| unsigned int pattern(unsigned int offset) { |
| unsigned int data = pattern_->pat[(offset >> busshift_) & pattern_->mask]; |
| if (inverse_) |
| data = ~data; |
| return data; |
| } |
| const AdlerChecksum *crc() {return crc_;} |
| unsigned int mask() {return pattern_->mask;} |
| unsigned int weight() {return weight_;} |
| const char *name() {return name_.c_str();} |
| |
| private: |
| int CalculateCrc(); |
| const struct PatternData *pattern_; |
| int busshift_; // Target data bus width. |
| bool inverse_; // Invert the data from the original pattern. |
| AdlerChecksum *crc_; // CRC of this pattern. |
| string name_; // The human readable pattern name. |
| int weight_; // This is the likelihood that this |
| // pattern will be chosen. |
| // We want to copy this! |
| // DISALLOW_COPY_AND_ASSIGN(Pattern); |
| }; |
| |
| // Object used to access global pattern list. |
| class PatternList { |
| public: |
| PatternList(); |
| ~PatternList(); |
| // Initialize pointers to global data patterns, and calculate CRC. |
| int Initialize(); |
| int Destroy(); |
| |
| // Return the pattern designated by index i. |
| Pattern *GetPattern(int i); |
| // Return a random pattern according to the specified weighted probability. |
| Pattern *GetRandomPattern(); |
| // Return the number of patterns available. |
| int Size() {return size_;} |
| |
| private: |
| vector<class Pattern> patterns_; |
| int weightcount_; // Total count of pattern weights. |
| unsigned int size_; |
| int initialized_; |
| DISALLOW_COPY_AND_ASSIGN(PatternList); |
| }; |
| |
| // CrcIncrement allows an abstracted way to add a 32bit |
| // value into a running CRC. This function should be fast, and |
| // generate meaningful CRCs for the types of data patterns that |
| // we are using here. |
| // This CRC formula may not be optimal, but it does work. |
| // It may be improved in the future. |
| static inline uint32 CrcIncrement(uint32 crc, uint32 expected, int index) { |
| uint32 addition = (expected ^ index); |
| uint32 carry = (addition & crc) >> 31; |
| |
| return crc + addition + carry; |
| } |
| |
| |
| #endif // STRESSAPPTEST_PATTERN_H_ |