src/worker.cc
// Memory copy work loop. Execute until marked done.
Memory copy work loop. Execute until marked done.
Memory copy work loop . Execute until marked done .
bool CopyThread::Work() {
  struct page_entry src;
  struct page_entry dst;
  bool result = true;
  int64 loops = 0;
  logprintf(9, "Log: Starting copy thread %d: cpu %s, mem %x\n",
            thread_num_, cpuset_format(&cpu_mask_).c_str(), tag_);
  while (IsReadyToRun()) {
    result = result && sat_->GetValid(&src, tag_);
    result = result && sat_->GetEmpty(&dst, tag_);
    if (!result) {
      logprintf(0, "Process Error: copy_thread failed to pop pages, "
                "bailing\n");
      break;
    }
    if (sat_->error_injection()) {
      if (loops == 8) {
        char *addr = reinterpret_cast<char*>(src.addr);
        int offset = random() % sat_->page_length();
        addr[offset] = 0xba;
      }
    }
    if (sat_->warm()) {
      CrcWarmCopyPage(&dst, &src);
    } else if (sat_->strict()) {
      CrcCopyPage(&dst, &src);
    } else {
      memcpy(dst.addr, src.addr, sat_->page_length());
      dst.pattern = src.pattern;
    }
    result = result && sat_->PutValid(&dst);
    result = result && sat_->PutEmpty(&src);
    YieldSelf();
    if (!result) {
      logprintf(0, "Process Error: copy_thread failed to push pages, "
                "bailing\n");
      break;
    }
    loops++;
  }
  pages_copied_ = loops;
  status_ = result;
  logprintf(9, "Log: Completed %d: Copy thread. Status %d, %d pages copied\n",
            thread_num_, status_, pages_copied_);
  return result;
}
bool CopyThread :: Work ( ) { struct page_entry src ; struct page_entry dst ; bool result = true ; int64 loops = 0 ; logprintf ( 9 , " \n " , thread_num_ , cpuset_format ( & cpu_mask_ ) . c_str ( ) , tag_ ) ; while ( IsReadyToRun ( ) ) { result = result && sat_ -> GetValid ( & src , tag_ ) ; result = result && sat_ -> GetEmpty ( & dst , tag_ ) ; if ( ! result ) { logprintf ( 0 , " " " \n " ) ; break ; } if ( sat_ -> error_injection ( ) ) { if ( loops == 8 ) { char * addr = reinterpret_cast < char * > ( src . addr ) ; int offset = random ( ) % sat_ -> page_length ( ) ; addr [ offset ] = 0xba ; } } if ( sat_ -> warm ( ) ) { CrcWarmCopyPage ( & dst , & src ) ; } else if ( sat_ -> strict ( ) ) { CrcCopyPage ( & dst , & src ) ; } else { memcpy ( dst . addr , src . addr , sat_ -> page_length ( ) ) ; dst . pattern = src . pattern ; } result = result && sat_ -> PutValid ( & dst ) ; result = result && sat_ -> PutEmpty ( & src ) ; YieldSelf ( ) ; if ( ! result ) { logprintf ( 0 , " " " \n " ) ; break ; } loops ++ ; } pages_copied_ = loops ; status_ = result ; logprintf ( 9 , " \n " , thread_num_ , status_ , pages_copied_ ) ; return result ; }
Memory copy work loop.
Memory copy work loop .
// Pop the needed pages. // Force errors for unittests. // We can use memcpy, or CRC check while we copy. // Copy worker-threads yield themselves at the end of each copy loop, // to avoid threads from preempting each other in the middle of the inner // copy-loop. Cooperations between Copy worker-threads results in less // unnecessary cache thrashing (which happens when context-switching in the // middle of the inner copy-loop).