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.
pattern(unsigned int offset)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 }
crc()68 const AdlerChecksum *crc() {return crc_;}
mask()69 unsigned int mask() {return pattern_->mask;}
weight()70 unsigned int weight() {return weight_;}
name()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.
Size()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.
CrcIncrement(uint32 crc,uint32 expected,int index)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