| // 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.cc : library of stressful data patterns |
| |
| #include <sys/types.h> |
| |
| // This file must work with autoconf on its public version, |
| // so these includes are correct. |
| #include "pattern.h" |
| #include "sattypes.h" |
| |
| // Static data patterns. |
| |
| static unsigned int walkingOnes_data[] = { |
| 0x00000001, 0x00000002, 0x00000004, 0x00000008, |
| 0x00000010, 0x00000020, 0x00000040, 0x00000080, |
| 0x00000100, 0x00000200, 0x00000400, 0x00000800, |
| 0x00001000, 0x00002000, 0x00004000, 0x00008000, |
| 0x00010000, 0x00020000, 0x00040000, 0x00080000, |
| 0x00100000, 0x00200000, 0x00400000, 0x00800000, |
| 0x01000000, 0x02000000, 0x04000000, 0x08000000, |
| 0x10000000, 0x20000000, 0x40000000, 0x80000000, |
| 0x40000000, 0x20000000, 0x10000000, 0x08000000, |
| 0x04000000, 0x02000000, 0x01000000, 0x00800000, |
| 0x00400000, 0x00200000, 0x00100000, 0x00080000, |
| 0x00040000, 0x00020000, 0x00010000, 0x00008000, |
| 0x00004000, 0x00002000, 0x00001000, 0x00000800, |
| 0x00000400, 0x00000200, 0x00000100, 0x00000080, |
| 0x00000040, 0x00000020, 0x00000010, 0x00000008, |
| 0x00000004, 0x00000002, 0x00000001, 0x00000000 |
| }; |
| static const struct PatternData walkingOnes = { |
| "walkingOnes", |
| walkingOnes_data, |
| (sizeof walkingOnes_data / sizeof walkingOnes_data[0]) - 1, |
| {1, 1, 2, 1} // Weight for choosing 32/64/128/256 bit wide of this pattern |
| }; |
| |
| static unsigned int walkingInvOnes_data[] = { |
| 0x00000001, 0xfffffffe, 0x00000002, 0xfffffffd, |
| 0x00000004, 0xfffffffb, 0x00000008, 0xfffffff7, |
| 0x00000010, 0xffffffef, 0x00000020, 0xffffffdf, |
| 0x00000040, 0xffffffbf, 0x00000080, 0xffffff7f, |
| 0x00000100, 0xfffffeff, 0x00000200, 0xfffffdff, |
| 0x00000400, 0xfffffbff, 0x00000800, 0xfffff7ff, |
| 0x00001000, 0xffffefff, 0x00002000, 0xffffdfff, |
| 0x00004000, 0xffffbfff, 0x00008000, 0xffff7fff, |
| 0x00010000, 0xfffeffff, 0x00020000, 0xfffdffff, |
| 0x00040000, 0xfffbffff, 0x00080000, 0xfff7ffff, |
| 0x00100000, 0xffefffff, 0x00200000, 0xffdfffff, |
| 0x00400000, 0xffbfffff, 0x00800000, 0xff7fffff, |
| 0x01000000, 0xfeffffff, 0x02000000, 0xfdffffff, |
| 0x04000000, 0xfbffffff, 0x08000000, 0xf7ffffff, |
| 0x10000000, 0xefffffff, 0x20000000, 0xdfffffff, |
| 0x40000000, 0xbfffffff, 0x80000000, 0x7fffffff, |
| 0x40000000, 0xbfffffff, 0x20000000, 0xdfffffff, |
| 0x10000000, 0xefffffff, 0x08000000, 0xf7ffffff, |
| 0x04000000, 0xfbffffff, 0x02000000, 0xfdffffff, |
| 0x01000000, 0xfeffffff, 0x00800000, 0xff7fffff, |
| 0x00400000, 0xffbfffff, 0x00200000, 0xffdfffff, |
| 0x00100000, 0xffefffff, 0x00080000, 0xfff7ffff, |
| 0x00040000, 0xfffbffff, 0x00020000, 0xfffdffff, |
| 0x00010000, 0xfffeffff, 0x00008000, 0xffff7fff, |
| 0x00004000, 0xffffbfff, 0x00002000, 0xffffdfff, |
| 0x00001000, 0xffffefff, 0x00000800, 0xfffff7ff, |
| 0x00000400, 0xfffffbff, 0x00000200, 0xfffffdff, |
| 0x00000100, 0xfffffeff, 0x00000080, 0xffffff7f, |
| 0x00000040, 0xffffffbf, 0x00000020, 0xffffffdf, |
| 0x00000010, 0xffffffef, 0x00000008, 0xfffffff7, |
| 0x00000004, 0xfffffffb, 0x00000002, 0xfffffffd, |
| 0x00000001, 0xfffffffe, 0x00000000, 0xffffffff |
| }; |
| static const struct PatternData walkingInvOnes = { |
| "walkingInvOnes", |
| walkingInvOnes_data, |
| (sizeof walkingInvOnes_data / sizeof walkingInvOnes_data[0]) - 1, |
| {2, 2, 5, 5} |
| }; |
| |
| static unsigned int walkingZeros_data[] = { |
| 0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7, |
| 0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f, |
| 0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff, |
| 0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff, |
| 0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff, |
| 0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff, |
| 0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff, |
| 0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff, |
| 0xbfffffff, 0xdfffffff, 0xefffffff, 0xf7ffffff, |
| 0xfbffffff, 0xfdffffff, 0xfeffffff, 0xff7fffff, |
| 0xffbfffff, 0xffdfffff, 0xffefffff, 0xfff7ffff, |
| 0xfffbffff, 0xfffdffff, 0xfffeffff, 0xffff7fff, |
| 0xffffbfff, 0xffffdfff, 0xffffefff, 0xfffff7ff, |
| 0xfffffbff, 0xfffffdff, 0xfffffeff, 0xffffff7f, |
| 0xffffffbf, 0xffffffdf, 0xffffffef, 0xfffffff7, |
| 0xfffffffb, 0xfffffffd, 0xfffffffe, 0xffffffff |
| }; |
| static const struct PatternData walkingZeros = { |
| "walkingZeros", |
| walkingZeros_data, |
| (sizeof walkingZeros_data / sizeof walkingZeros_data[0]) - 1, |
| {1, 1, 2, 1} |
| }; |
| |
| static unsigned int OneZero_data[] = { 0x00000000, 0xffffffff}; |
| static const struct PatternData OneZero = { |
| "OneZero", |
| OneZero_data, |
| (sizeof OneZero_data / sizeof OneZero_data[0]) - 1, |
| {5, 5, 15, 5} |
| }; |
| |
| static unsigned int JustZero_data[] = { 0x00000000, 0x00000000}; |
| static const struct PatternData JustZero = { |
| "JustZero", |
| JustZero_data, |
| (sizeof JustZero_data / sizeof JustZero_data[0]) - 1, |
| {2, 0, 0, 0} |
| }; |
| |
| static unsigned int JustOne_data[] = { 0xffffffff, 0xffffffff}; |
| static const struct PatternData JustOne = { |
| "JustOne", |
| JustOne_data, |
| (sizeof JustOne_data / sizeof JustOne_data[0]) - 1, |
| {2, 0, 0, 0} |
| }; |
| |
| static unsigned int JustFive_data[] = { 0x55555555, 0x55555555}; |
| static const struct PatternData JustFive = { |
| "JustFive", |
| JustFive_data, |
| (sizeof JustFive_data / sizeof JustFive_data[0]) - 1, |
| {2, 0, 0, 0} |
| }; |
| |
| static unsigned int JustA_data[] = { 0xaaaaaaaa, 0xaaaaaaaa}; |
| static const struct PatternData JustA = { |
| "JustA", |
| JustA_data, |
| (sizeof JustA_data / sizeof JustA_data[0]) - 1, |
| {2, 0, 0, 0} |
| }; |
| |
| static unsigned int FiveA_data[] = { 0x55555555, 0xaaaaaaaa}; |
| static const struct PatternData FiveA = { |
| "FiveA", |
| FiveA_data, |
| (sizeof FiveA_data / sizeof FiveA_data[0]) - 1, |
| {1, 1, 1, 1} |
| }; |
| |
| static unsigned int FiveA8_data[] = { |
| 0x5aa5a55a, 0xa55a5aa5, 0xa55a5aa5, 0x5aa5a55a |
| }; |
| static const struct PatternData FiveA8 = { |
| "FiveA8", |
| FiveA8_data, |
| (sizeof FiveA8_data / sizeof FiveA8_data[0]) - 1, |
| {1, 1, 1, 1} |
| }; |
| |
| static unsigned int Long8b10b_data[] = { 0x16161616, 0x16161616 }; |
| static const struct PatternData Long8b10b = { |
| "Long8b10b", |
| Long8b10b_data, |
| (sizeof Long8b10b_data / sizeof Long8b10b_data[0]) - 1, |
| {2, 0, 0, 0} |
| }; |
| |
| static unsigned int Short8b10b_data[] = { 0xb5b5b5b5, 0xb5b5b5b5 }; |
| static const struct PatternData Short8b10b = { |
| "Short8b10b", |
| Short8b10b_data, |
| (sizeof Short8b10b_data / sizeof Short8b10b_data[0]) - 1, |
| {2, 0, 0, 0} |
| }; |
| |
| static unsigned int Checker8b10b_data[] = { 0xb5b5b5b5, 0x4a4a4a4a }; |
| static const struct PatternData Checker8b10b = { |
| "Checker8b10b", |
| Checker8b10b_data, |
| (sizeof Checker8b10b_data / sizeof Checker8b10b_data[0]) - 1, |
| {1, 0, 0, 1} |
| }; |
| |
| static unsigned int Five7_data[] = { 0x55555557, 0x55575555 }; |
| static const struct PatternData Five7 = { |
| "Five7", |
| Five7_data, |
| (sizeof Five7_data / sizeof Five7_data[0]) - 1, |
| {0, 2, 0, 0} |
| }; |
| |
| static unsigned int Zero2fd_data[] = { 0x00020002, 0xfffdfffd }; |
| static const struct PatternData Zero2fd = { |
| "Zero2fd", |
| Zero2fd_data, |
| (sizeof Zero2fd_data / sizeof Zero2fd_data[0]) - 1, |
| {0, 2, 0, 0} |
| }; |
| |
| // Extern array of useable patterns. |
| static const struct PatternData pattern_array[] = { |
| walkingOnes, |
| walkingInvOnes, |
| walkingZeros, |
| OneZero, |
| JustZero, |
| JustOne, |
| JustFive, |
| JustA, |
| FiveA, |
| FiveA8, |
| Long8b10b, |
| Short8b10b, |
| Checker8b10b, |
| Five7, |
| Zero2fd, |
| }; |
| static const int pattern_array_size = |
| sizeof pattern_array / sizeof pattern_array[0]; |
| |
| Pattern::Pattern() { |
| crc_ = NULL; |
| } |
| |
| Pattern::~Pattern() { |
| if (crc_ != NULL) { |
| delete crc_; |
| } |
| } |
| |
| // Calculate CRC for this pattern. This must match |
| // the CRC calculation in worker.cc. |
| int Pattern::CalculateCrc() { |
| // TODO(johnhuang): |
| // Consider refactoring to the form: |
| // while (i < count) AdlerInc(uint64, uint64, AdlerChecksum*) |
| uint64 a1 = 1; |
| uint64 a2 = 1; |
| uint64 b1 = 0; |
| uint64 b2 = 0; |
| |
| // checksum is calculated using only the first 4096 bytes of data. |
| int i = 0; |
| int blocksize = 4096; |
| int count = blocksize / sizeof i; |
| while (i < count) { |
| a1 += pattern(i); |
| b1 += a1; |
| i++; |
| a1 += pattern(i); |
| b1 += a1; |
| i++; |
| |
| a2 += pattern(i); |
| b2 += a2; |
| i++; |
| a2 += pattern(i); |
| b2 += a2; |
| i++; |
| } |
| if (crc_ != NULL) { |
| delete crc_; |
| } |
| crc_ = new AdlerChecksum(); |
| crc_->Set(a1, a2, b1, b2); |
| return 0; |
| } |
| |
| // Initialize pattern's CRC. |
| int Pattern::Initialize(const struct PatternData &pattern_init, |
| int buswidth, |
| bool invert, |
| int weight) { |
| int result = 1; |
| |
| pattern_ = &pattern_init; |
| busshift_ = 2; |
| inverse_ = invert; |
| weight_ = weight; |
| |
| name_.clear(); |
| name_.append(pattern_->name); |
| |
| if (invert) |
| name_.append("~"); |
| |
| if (buswidth == 32) { |
| name_.append("32"); |
| busshift_ = 0; |
| } else if (buswidth == 64) { |
| name_.append("64"); |
| busshift_ = 1; |
| } else if (buswidth == 128) { |
| name_.append("128"); |
| busshift_ = 2; |
| } else if (buswidth == 256) { |
| name_.append("256"); |
| busshift_ = 3; |
| } else { |
| logprintf(0, "Process Error: Confused by bus width %d\n", |
| buswidth); |
| name_.append("Broken"); |
| result = 0; |
| } |
| |
| CalculateCrc(); |
| |
| return result; |
| } |
| |
| |
| PatternList::PatternList() { |
| size_= 0; |
| initialized_ = 0; |
| } |
| |
| PatternList::~PatternList() { |
| if (initialized_) { |
| Destroy(); |
| } |
| } |
| |
| // Fill in the class with references to the static data patterns |
| int PatternList::Initialize() { |
| int patterncount = 0; |
| int weightcount = 0; |
| |
| patterns_.resize(pattern_array_size * 8); |
| for (int i = 0; i < pattern_array_size; i++) { |
| // Non inverted. |
| weightcount += pattern_array[i].weight[0]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 32, false, |
| pattern_array[i].weight[0]); |
| weightcount += pattern_array[i].weight[1]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 64, false, |
| pattern_array[i].weight[1]); |
| weightcount += pattern_array[i].weight[2]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 128, false, |
| pattern_array[i].weight[2]); |
| weightcount += pattern_array[i].weight[3]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 256, false, |
| pattern_array[i].weight[3]); |
| |
| // Inverted. |
| weightcount += pattern_array[i].weight[0]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 32, true, |
| pattern_array[i].weight[0]); |
| weightcount += pattern_array[i].weight[1]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 64, true, |
| pattern_array[i].weight[1]); |
| weightcount += pattern_array[i].weight[2]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 128, true, |
| pattern_array[i].weight[2]); |
| weightcount += pattern_array[i].weight[3]; |
| patterns_[patterncount++].Initialize(pattern_array[i], 256, true, |
| pattern_array[i].weight[3]); |
| } |
| size_ = patterncount; |
| weightcount_ = weightcount; |
| initialized_ = 1; |
| |
| logprintf(12, "Log: initialized %d data patterns\n", size_); |
| |
| return 1; |
| } |
| |
| // Free the stuff. |
| int PatternList::Destroy() { |
| if (!initialized_) |
| return 0; |
| |
| patterns_.clear(); |
| size_ = 0; |
| initialized_ = 0; |
| |
| return 1; |
| } |
| |
| // Return pattern numbered "i" |
| Pattern *PatternList::GetPattern(int i) { |
| if (static_cast<unsigned int>(i) < size_) { |
| return &patterns_[i]; |
| } |
| |
| logprintf(0, "Process Error: Out of bounds pattern access\n"); |
| return 0; |
| } |
| |
| // Return a randomly selected pattern. |
| Pattern *PatternList::GetRandomPattern() { |
| unsigned int target = random(); |
| target = target % weightcount_; |
| |
| unsigned int i = 0; |
| unsigned int sum = 0; |
| while (target > sum) { |
| sum += patterns_[i].weight(); |
| i++; |
| } |
| if (i < size_) { |
| return &patterns_[i]; |
| } |
| |
| logprintf(0, "Process Error: Out of bounds pattern access\n"); |
| return 0; |
| } |