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.cc : library of stressful data patterns 16 17 #include <sys/types.h> 18 19 // This file must work with autoconf on its public version, 20 // so these includes are correct. 21 #include "pattern.h" 22 #include "sattypes.h" 23 24 // Static data patterns. 25 26 static unsigned int walkingOnes_data[] = { 27 0x00000001, 0x00000002, 0x00000004, 0x00000008, 28 0x00000010, 0x00000020, 0x00000040, 0x00000080, 29 0x00000100, 0x00000200, 0x00000400, 0x00000800, 30 0x00001000, 0x00002000, 0x00004000, 0x00008000, 31 0x00010000, 0x00020000, 0x00040000, 0x00080000, 32 0x00100000, 0x00200000, 0x00400000, 0x00800000, 33 0x01000000, 0x02000000, 0x04000000, 0x08000000, 34 0x10000000, 0x20000000, 0x40000000, 0x80000000, 35 0x40000000, 0x20000000, 0x10000000, 0x08000000, 36 0x04000000, 0x02000000, 0x01000000, 0x00800000, 37 0x00400000, 0x00200000, 0x00100000, 0x00080000, 38 0x00040000, 0x00020000, 0x00010000, 0x00008000, 39 0x00004000, 0x00002000, 0x00001000, 0x00000800, 40 0x00000400, 0x00000200, 0x00000100, 0x00000080, 41 0x00000040, 0x00000020, 0x00000010, 0x00000008, 42 0x00000004, 0x00000002, 0x00000001, 0x00000000 43 }; 44 static const struct PatternData walkingOnes = { 45 "walkingOnes", 46 walkingOnes_data, 47 (sizeof walkingOnes_data / sizeof walkingOnes_data[0]) - 1, 48 {1, 1, 2, 1} // Weight for choosing 32/64/128/256 bit wide of this pattern 49 }; 50 51 static unsigned int walkingInvOnes_data[] = { 52 0x00000001, 0xfffffffe, 0x00000002, 0xfffffffd, 53 0x00000004, 0xfffffffb, 0x00000008, 0xfffffff7, 54 0x00000010, 0xffffffef, 0x00000020, 0xffffffdf, 55 0x00000040, 0xffffffbf, 0x00000080, 0xffffff7f, 56 0x00000100, 0xfffffeff, 0x00000200, 0xfffffdff, 57 0x00000400, 0xfffffbff, 0x00000800, 0xfffff7ff, 58 0x00001000, 0xffffefff, 0x00002000, 0xffffdfff, 59 0x00004000, 0xffffbfff, 0x00008000, 0xffff7fff, 60 0x00010000, 0xfffeffff, 0x00020000, 0xfffdffff, 61 0x00040000, 0xfffbffff, 0x00080000, 0xfff7ffff, 62 0x00100000, 0xffefffff, 0x00200000, 0xffdfffff, 63 0x00400000, 0xffbfffff, 0x00800000, 0xff7fffff, 64 0x01000000, 0xfeffffff, 0x02000000, 0xfdffffff, 65 0x04000000, 0xfbffffff, 0x08000000, 0xf7ffffff, 66 0x10000000, 0xefffffff, 0x20000000, 0xdfffffff, 67 0x40000000, 0xbfffffff, 0x80000000, 0x7fffffff, 68 0x40000000, 0xbfffffff, 0x20000000, 0xdfffffff, 69 0x10000000, 0xefffffff, 0x08000000, 0xf7ffffff, 70 0x04000000, 0xfbffffff, 0x02000000, 0xfdffffff, 71 0x01000000, 0xfeffffff, 0x00800000, 0xff7fffff, 72 0x00400000, 0xffbfffff, 0x00200000, 0xffdfffff, 73 0x00100000, 0xffefffff, 0x00080000, 0xfff7ffff, 74 0x00040000, 0xfffbffff, 0x00020000, 0xfffdffff, 75 0x00010000, 0xfffeffff, 0x00008000, 0xffff7fff, 76 0x00004000, 0xffffbfff, 0x00002000, 0xffffdfff, 77 0x00001000, 0xffffefff, 0x00000800, 0xfffff7ff, 78 0x00000400, 0xfffffbff, 0x00000200, 0xfffffdff, 79 0x00000100, 0xfffffeff, 0x00000080, 0xffffff7f, 80 0x00000040, 0xffffffbf, 0x00000020, 0xffffffdf, 81 0x00000010, 0xffffffef, 0x00000008, 0xfffffff7, 82 0x00000004, 0xfffffffb, 0x00000002, 0xfffffffd, 83 0x00000001, 0xfffffffe, 0x00000000, 0xffffffff 84 }; 85 static const struct PatternData walkingInvOnes = { 86 "walkingInvOnes", 87 walkingInvOnes_data, 88 (sizeof walkingInvOnes_data / sizeof walkingInvOnes_data[0]) - 1, 89 {2, 2, 5, 5} 90 }; 91 92 static unsigned int walkingZeros_data[] = { 93 0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7, 94 0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f, 95 0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff, 96 0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff, 97 0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff, 98 0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff, 99 0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff, 100 0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff, 101 0xbfffffff, 0xdfffffff, 0xefffffff, 0xf7ffffff, 102 0xfbffffff, 0xfdffffff, 0xfeffffff, 0xff7fffff, 103 0xffbfffff, 0xffdfffff, 0xffefffff, 0xfff7ffff, 104 0xfffbffff, 0xfffdffff, 0xfffeffff, 0xffff7fff, 105 0xffffbfff, 0xffffdfff, 0xffffefff, 0xfffff7ff, 106 0xfffffbff, 0xfffffdff, 0xfffffeff, 0xffffff7f, 107 0xffffffbf, 0xffffffdf, 0xffffffef, 0xfffffff7, 108 0xfffffffb, 0xfffffffd, 0xfffffffe, 0xffffffff 109 }; 110 static const struct PatternData walkingZeros = { 111 "walkingZeros", 112 walkingZeros_data, 113 (sizeof walkingZeros_data / sizeof walkingZeros_data[0]) - 1, 114 {1, 1, 2, 1} 115 }; 116 117 static unsigned int OneZero_data[] = { 0x00000000, 0xffffffff}; 118 static const struct PatternData OneZero = { 119 "OneZero", 120 OneZero_data, 121 (sizeof OneZero_data / sizeof OneZero_data[0]) - 1, 122 {5, 5, 15, 5} 123 }; 124 125 static unsigned int JustZero_data[] = { 0x00000000, 0x00000000}; 126 static const struct PatternData JustZero = { 127 "JustZero", 128 JustZero_data, 129 (sizeof JustZero_data / sizeof JustZero_data[0]) - 1, 130 {2, 0, 0, 0} 131 }; 132 133 static unsigned int JustOne_data[] = { 0xffffffff, 0xffffffff}; 134 static const struct PatternData JustOne = { 135 "JustOne", 136 JustOne_data, 137 (sizeof JustOne_data / sizeof JustOne_data[0]) - 1, 138 {2, 0, 0, 0} 139 }; 140 141 static unsigned int JustFive_data[] = { 0x55555555, 0x55555555}; 142 static const struct PatternData JustFive = { 143 "JustFive", 144 JustFive_data, 145 (sizeof JustFive_data / sizeof JustFive_data[0]) - 1, 146 {2, 0, 0, 0} 147 }; 148 149 static unsigned int JustA_data[] = { 0xaaaaaaaa, 0xaaaaaaaa}; 150 static const struct PatternData JustA = { 151 "JustA", 152 JustA_data, 153 (sizeof JustA_data / sizeof JustA_data[0]) - 1, 154 {2, 0, 0, 0} 155 }; 156 157 static unsigned int FiveA_data[] = { 0x55555555, 0xaaaaaaaa}; 158 static const struct PatternData FiveA = { 159 "FiveA", 160 FiveA_data, 161 (sizeof FiveA_data / sizeof FiveA_data[0]) - 1, 162 {1, 1, 1, 1} 163 }; 164 165 static unsigned int FiveA8_data[] = { 166 0x5aa5a55a, 0xa55a5aa5, 0xa55a5aa5, 0x5aa5a55a 167 }; 168 static const struct PatternData FiveA8 = { 169 "FiveA8", 170 FiveA8_data, 171 (sizeof FiveA8_data / sizeof FiveA8_data[0]) - 1, 172 {1, 1, 1, 1} 173 }; 174 175 static unsigned int Long8b10b_data[] = { 0x16161616, 0x16161616 }; 176 static const struct PatternData Long8b10b = { 177 "Long8b10b", 178 Long8b10b_data, 179 (sizeof Long8b10b_data / sizeof Long8b10b_data[0]) - 1, 180 {2, 0, 0, 0} 181 }; 182 183 static unsigned int Short8b10b_data[] = { 0xb5b5b5b5, 0xb5b5b5b5 }; 184 static const struct PatternData Short8b10b = { 185 "Short8b10b", 186 Short8b10b_data, 187 (sizeof Short8b10b_data / sizeof Short8b10b_data[0]) - 1, 188 {2, 0, 0, 0} 189 }; 190 191 static unsigned int Checker8b10b_data[] = { 0xb5b5b5b5, 0x4a4a4a4a }; 192 static const struct PatternData Checker8b10b = { 193 "Checker8b10b", 194 Checker8b10b_data, 195 (sizeof Checker8b10b_data / sizeof Checker8b10b_data[0]) - 1, 196 {1, 0, 0, 1} 197 }; 198 199 static unsigned int Five7_data[] = { 0x55555557, 0x55575555 }; 200 static const struct PatternData Five7 = { 201 "Five7", 202 Five7_data, 203 (sizeof Five7_data / sizeof Five7_data[0]) - 1, 204 {0, 2, 0, 0} 205 }; 206 207 static unsigned int Zero2fd_data[] = { 0x00020002, 0xfffdfffd }; 208 static const struct PatternData Zero2fd = { 209 "Zero2fd", 210 Zero2fd_data, 211 (sizeof Zero2fd_data / sizeof Zero2fd_data[0]) - 1, 212 {0, 2, 0, 0} 213 }; 214 215 // Extern array of useable patterns. 216 static const struct PatternData pattern_array[] = { 217 walkingOnes, 218 walkingInvOnes, 219 walkingZeros, 220 OneZero, 221 JustZero, 222 JustOne, 223 JustFive, 224 JustA, 225 FiveA, 226 FiveA8, 227 Long8b10b, 228 Short8b10b, 229 Checker8b10b, 230 Five7, 231 Zero2fd, 232 }; 233 static const int pattern_array_size = 234 sizeof pattern_array / sizeof pattern_array[0]; 235 236 Pattern::Pattern() { 237 crc_ = NULL; 238 } 239 240 Pattern::~Pattern() { 241 if (crc_ != NULL) { 242 delete crc_; 243 } 244 } 245 246 // Calculate CRC for this pattern. This must match 247 // the CRC calculation in worker.cc. 248 int Pattern::CalculateCrc() { 249 // TODO(johnhuang): 250 // Consider refactoring to the form: 251 // while (i < count) AdlerInc(uint64, uint64, AdlerChecksum*) 252 uint64 a1 = 1; 253 uint64 a2 = 1; 254 uint64 b1 = 0; 255 uint64 b2 = 0; 256 257 // checksum is calculated using only the first 4096 bytes of data. 258 int i = 0; 259 int blocksize = 4096; 260 int count = blocksize / sizeof i; 261 while (i < count) { 262 a1 += pattern(i); 263 b1 += a1; 264 i++; 265 a1 += pattern(i); 266 b1 += a1; 267 i++; 268 269 a2 += pattern(i); 270 b2 += a2; 271 i++; 272 a2 += pattern(i); 273 b2 += a2; 274 i++; 275 } 276 if (crc_ != NULL) { 277 delete crc_; 278 } 279 crc_ = new AdlerChecksum(); 280 crc_->Set(a1, a2, b1, b2); 281 return 0; 282 } 283 284 // Initialize pattern's CRC. 285 int Pattern::Initialize(const struct PatternData &pattern_init, 286 int buswidth, 287 bool invert, 288 int weight) { 289 int result = 1; 290 291 pattern_ = &pattern_init; 292 busshift_ = 2; 293 inverse_ = invert; 294 weight_ = weight; 295 296 name_.clear(); 297 name_.append(pattern_->name); 298 299 if (invert) 300 name_.append("~"); 301 302 if (buswidth == 32) { 303 name_.append("32"); 304 busshift_ = 0; 305 } else if (buswidth == 64) { 306 name_.append("64"); 307 busshift_ = 1; 308 } else if (buswidth == 128) { 309 name_.append("128"); 310 busshift_ = 2; 311 } else if (buswidth == 256) { 312 name_.append("256"); 313 busshift_ = 3; 314 } else { 315 logprintf(0, "Process Error: Confused by bus width %d\n", 316 buswidth); 317 name_.append("Broken"); 318 result = 0; 319 } 320 321 CalculateCrc(); 322 323 return result; 324 } 325 326 327 PatternList::PatternList() { 328 size_= 0; 329 initialized_ = 0; 330 } 331 332 PatternList::~PatternList() { 333 if (initialized_) { 334 Destroy(); 335 } 336 } 337 338 // Fill in the class with references to the static data patterns 339 int PatternList::Initialize() { 340 int patterncount = 0; 341 int weightcount = 0; 342 343 patterns_.resize(pattern_array_size * 8); 344 for (int i = 0; i < pattern_array_size; i++) { 345 // Non inverted. 346 weightcount += pattern_array[i].weight[0]; 347 patterns_[patterncount++].Initialize(pattern_array[i], 32, false, 348 pattern_array[i].weight[0]); 349 weightcount += pattern_array[i].weight[1]; 350 patterns_[patterncount++].Initialize(pattern_array[i], 64, false, 351 pattern_array[i].weight[1]); 352 weightcount += pattern_array[i].weight[2]; 353 patterns_[patterncount++].Initialize(pattern_array[i], 128, false, 354 pattern_array[i].weight[2]); 355 weightcount += pattern_array[i].weight[3]; 356 patterns_[patterncount++].Initialize(pattern_array[i], 256, false, 357 pattern_array[i].weight[3]); 358 359 // Inverted. 360 weightcount += pattern_array[i].weight[0]; 361 patterns_[patterncount++].Initialize(pattern_array[i], 32, true, 362 pattern_array[i].weight[0]); 363 weightcount += pattern_array[i].weight[1]; 364 patterns_[patterncount++].Initialize(pattern_array[i], 64, true, 365 pattern_array[i].weight[1]); 366 weightcount += pattern_array[i].weight[2]; 367 patterns_[patterncount++].Initialize(pattern_array[i], 128, true, 368 pattern_array[i].weight[2]); 369 weightcount += pattern_array[i].weight[3]; 370 patterns_[patterncount++].Initialize(pattern_array[i], 256, true, 371 pattern_array[i].weight[3]); 372 } 373 size_ = patterncount; 374 weightcount_ = weightcount; 375 initialized_ = 1; 376 377 logprintf(12, "Log: initialized %d data patterns\n", size_); 378 379 return 1; 380 } 381 382 // Free the stuff. 383 int PatternList::Destroy() { 384 if (!initialized_) 385 return 0; 386 387 patterns_.clear(); 388 size_ = 0; 389 initialized_ = 0; 390 391 return 1; 392 } 393 394 // Return pattern numbered "i" 395 Pattern *PatternList::GetPattern(int i) { 396 if (static_cast<unsigned int>(i) < size_) { 397 return &patterns_[i]; 398 } 399 400 logprintf(0, "Process Error: Out of bounds pattern access\n"); 401 return 0; 402 } 403 404 // Return a randomly selected pattern. 405 Pattern *PatternList::GetRandomPattern() { 406 unsigned int target = random(); 407 target = target % weightcount_; 408 409 unsigned int i = 0; 410 unsigned int sum = 0; 411 while (target > sum) { 412 sum += patterns_[i].weight(); 413 i++; 414 } 415 if (i < size_) { 416 return &patterns_[i]; 417 } 418 419 logprintf(0, "Process Error: Out of bounds pattern access\n"); 420 return 0; 421 } 422