src/worker.cc
// Do a word by word result check of a region.
// Print errors on mismatches.
Do a word by word result check of a region.
Print errors on mismatches.
Do a word by word result check of a region . Print errors on mismatches .
int WorkerThread::CheckRegion(void *addr,
                              class Pattern *pattern,
                              int64 length,
                              int offset,
                              int64 pattern_offset) {
  uint64 *memblock = static_cast<uint64*>(addr);
  const int kErrorLimit = 128;
  int errors = 0;
  int overflowerrors = 0;  
  bool page_error = false;
  string errormessage("Hardware Error");
  struct ErrorRecord
    recorded[kErrorLimit];  
  for (int i = 0; i < length / wordsize_; i++) {
    uint64 actual = memblock[i];
    uint64 expected;
    datacast_t data;
    int index = 2 * i + pattern_offset;
    data.l32.l = pattern->pattern(index);
    data.l32.h = pattern->pattern(index + 1);
    expected = data.l64;
    if (tag_mode_ && ((reinterpret_cast<uint64>(&memblock[i]) & 0x3f) == 0)) {
      expected = addr_to_tag(&memblock[i]);
    }
    if (actual != expected) {
      if (errors < kErrorLimit) {
        recorded[errors].actual = actual;
        recorded[errors].expected = expected;
        recorded[errors].vaddr = &memblock[i];
        errors++;
      } else {
        page_error = true;
        logprintf(10, "Log: Error record overflow, too many miscompares!\n");
        errormessage = "Page Error";
        break;
      }
    }
  }
  if (page_error && !tag_mode_) {
    int patsize = patternlist_->Size();
    for (int pat = 0; pat < patsize; pat++) {
      class Pattern *altpattern = patternlist_->GetPattern(pat);
      const int kGood = 0;
      const int kBad = 1;
      const int kGoodAgain = 2;
      const int kNoMatch = 3;
      int state = kGood;
      unsigned int badstart = 0;
      unsigned int badend = 0;
      if (pattern == altpattern)
        continue;
      for (int i = 0; i < length / wordsize_; i++) {
        uint64 actual = memblock[i];
        datacast_t expected;
        datacast_t possible;
        int index = 2 * i + pattern_offset;
        expected.l32.l = pattern->pattern(index);
        expected.l32.h = pattern->pattern(index + 1);
        possible.l32.l = pattern->pattern(index);
        possible.l32.h = pattern->pattern(index + 1);
        if (state == kGood) {
          if (actual == expected.l64) {
            continue;
          } else if (actual == possible.l64) {
            badstart = i;
            badend = i;
            state = kBad;
            continue;
          } else {
            state = kNoMatch;
            break;
          }
        } else if (state == kBad) {
          if (actual == possible.l64) {
            badend = i;
            continue;
          } else if (actual == expected.l64) {
            state = kGoodAgain;
            continue;
          } else {
            state = kNoMatch;
            break;
          }
        } else if (state == kGoodAgain) {
          if (actual == expected.l64) {
            continue;
          } else {
            state = kNoMatch;
            break;
          }
        }
      }
      if ((state == kGoodAgain) || (state == kBad)) {
        unsigned int blockerrors = badend - badstart + 1;
        errormessage = "Block Error";
        ProcessError(&recorded[0], 0, errormessage.c_str());
        logprintf(0, "Block Error: (%p) pattern %s instead of %s, "
                  "%d bytes from offset 0x%x to 0x%x\n",
                  &memblock[badstart],
                  altpattern->name(), pattern->name(),
                  blockerrors * wordsize_,
                  offset + badstart * wordsize_,
                  offset + badend * wordsize_);
        errorcount_ += blockerrors;
        return blockerrors;
      }
    }
  }
  for (int err = 0; err < errors; err++) {
    int priority = 5;
    if (errorcount_ + err < 30)
      priority = 0;  
    ProcessError(&recorded[err], priority, errormessage.c_str());
  }
  if (page_error) {
    int error_recount = 0;
    for (int i = 0; i < length / wordsize_; i++) {
      uint64 actual = memblock[i];
      uint64 expected;
      datacast_t data;
      int index = 2 * i + pattern_offset;
      data.l32.l = pattern->pattern(index);
      data.l32.h = pattern->pattern(index + 1);
      expected = data.l64;
      if (tag_mode_ && ((reinterpret_cast<uint64>(&memblock[i]) & 0x3f) == 0)) {
        expected = addr_to_tag(&memblock[i]);
      }
      if (actual != expected) {
        if (error_recount < kErrorLimit) {
          error_recount++;
        } else {
          struct ErrorRecord er;
          er.actual = actual;
          er.expected = expected;
          er.vaddr = &memblock[i];
          ProcessError(&er, 12, errormessage.c_str());
          overflowerrors++;
        }
      }
    }
  }
  errorcount_ += errors + overflowerrors;
  return errors + overflowerrors;
}
int WorkerThread :: CheckRegion ( void * addr , class Pattern * pattern , int64 length , int offset , int64 pattern_offset ) { uint64 * memblock = static_cast < uint64 * > ( addr ) ; const int kErrorLimit = 128 ; int errors = 0 ; int overflowerrors = 0 ; bool page_error = false ; string errormessage ( " " ) ; struct ErrorRecord recorded [ kErrorLimit ] ; for ( int i = 0 ; i < length / wordsize_ ; i ++ ) { uint64 actual = memblock [ i ] ; uint64 expected ; datacast_t data ; int index = 2 * i + pattern_offset ; data . l32 . l = pattern -> pattern ( index ) ; data . l32 . h = pattern -> pattern ( index + 1 ) ; expected = data . l64 ; if ( tag_mode_ && ( ( reinterpret_cast < uint64 > ( & memblock [ i ] ) & 0x3f ) == 0 ) ) { expected = addr_to_tag ( & memblock [ i ] ) ; } if ( actual != expected ) { if ( errors < kErrorLimit ) { recorded [ errors ] . actual = actual ; recorded [ errors ] . expected = expected ; recorded [ errors ] . vaddr = & memblock [ i ] ; errors ++ ; } else { page_error = true ; logprintf ( 10 , " \n " ) ; errormessage = " " ; break ; } } } if ( page_error && ! tag_mode_ ) { int patsize = patternlist_ -> Size ( ) ; for ( int pat = 0 ; pat < patsize ; pat ++ ) { class Pattern * altpattern = patternlist_ -> GetPattern ( pat ) ; const int kGood = 0 ; const int kBad = 1 ; const int kGoodAgain = 2 ; const int kNoMatch = 3 ; int state = kGood ; unsigned int badstart = 0 ; unsigned int badend = 0 ; if ( pattern == altpattern ) continue ; for ( int i = 0 ; i < length / wordsize_ ; i ++ ) { uint64 actual = memblock [ i ] ; datacast_t expected ; datacast_t possible ; int index = 2 * i + pattern_offset ; expected . l32 . l = pattern -> pattern ( index ) ; expected . l32 . h = pattern -> pattern ( index + 1 ) ; possible . l32 . l = pattern -> pattern ( index ) ; possible . l32 . h = pattern -> pattern ( index + 1 ) ; if ( state == kGood ) { if ( actual == expected . l64 ) { continue ; } else if ( actual == possible . l64 ) { badstart = i ; badend = i ; state = kBad ; continue ; } else { state = kNoMatch ; break ; } } else if ( state == kBad ) { if ( actual == possible . l64 ) { badend = i ; continue ; } else if ( actual == expected . l64 ) { state = kGoodAgain ; continue ; } else { state = kNoMatch ; break ; } } else if ( state == kGoodAgain ) { if ( actual == expected . l64 ) { continue ; } else { state = kNoMatch ; break ; } } } if ( ( state == kGoodAgain ) || ( state == kBad ) ) { unsigned int blockerrors = badend - badstart + 1 ; errormessage = " " ; ProcessError ( & recorded [ 0 ] , 0 , errormessage . c_str ( ) ) ; logprintf ( 0 , " " " \n " , & memblock [ badstart ] , altpattern -> name ( ) , pattern -> name ( ) , blockerrors * wordsize_ , offset + badstart * wordsize_ , offset + badend * wordsize_ ) ; errorcount_ += blockerrors ; return blockerrors ; } } } for ( int err = 0 ; err < errors ; err ++ ) { int priority = 5 ; if ( errorcount_ + err < 30 ) priority = 0 ; ProcessError ( & recorded [ err ] , priority , errormessage . c_str ( ) ) ; } if ( page_error ) { int error_recount = 0 ; for ( int i = 0 ; i < length / wordsize_ ; i ++ ) { uint64 actual = memblock [ i ] ; uint64 expected ; datacast_t data ; int index = 2 * i + pattern_offset ; data . l32 . l = pattern -> pattern ( index ) ; data . l32 . h = pattern -> pattern ( index + 1 ) ; expected = data . l64 ; if ( tag_mode_ && ( ( reinterpret_cast < uint64 > ( & memblock [ i ] ) & 0x3f ) == 0 ) ) { expected = addr_to_tag ( & memblock [ i ] ) ; } if ( actual != expected ) { if ( error_recount < kErrorLimit ) { error_recount ++ ; } else { struct ErrorRecord er ; er . actual = actual ; er . expected = expected ; er . vaddr = & memblock [ i ] ; ProcessError ( & er , 12 , errormessage . c_str ( ) ) ; overflowerrors ++ ; } } } } errorcount_ += errors + overflowerrors ; return errors + overflowerrors ; }
Do a word by word result check of a region.
Do a word by word result check of a region .
// Count of overflowed errors. // Queued errors for later printing. // For each word in the data region. // Determine the value that should be there. // Check tags if necessary. // If the value is incorrect, save an error record for later printing. // If we have overflowed the error queue, just print the errors now. // Find if this is a whole block corruption. // Don't match against ourself! // Determine the value that should be there. // Process error queue after all errors have been recorded. // Bump up the priority for the first few errors. // For each word in the data region. // Determine the value that should be there. // Check tags if necessary. // If the value is incorrect, save an error record for later printing. // We already reported these. // If we have overflowed the error queue, print the errors now. // Do the error printout. This will take a long time and // likely change the machine state. // Keep track of observed errors.