func: static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
  
                                  int64_t max_ns)
  
  {
  
      bool final = max_ns < 0;
  
      int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
  
      int examined = 0, sent = 0;
  
      int index = spapr->htab_save_index;
  
      int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
  
  
  
      assert(!spapr->htab_first_pass);
  
  
  
      do {
  
          int chunkstart, invalidstart;
  
  
  
          /* Consume non-dirty HPTEs */
  
          while ((index < htabslots)
  
                 && !HPTE_DIRTY(HPTE(spapr->htab, index))) {
  
              index++;
  
              examined++;
  
          }
  
  
  
          chunkstart = index;
  
          /* Consume valid dirty HPTEs */
  
          while ((index < htabslots)
  
                 && HPTE_DIRTY(HPTE(spapr->htab, index))
  
                 && HPTE_VALID(HPTE(spapr->htab, index))) {
  
              CLEAN_HPTE(HPTE(spapr->htab, index));
  
              index++;
  
              examined++;
  
          }
  
  
  
          invalidstart = index;
  
          /* Consume invalid dirty HPTEs */
  
          while ((index < htabslots)
  
                 && HPTE_DIRTY(HPTE(spapr->htab, index))
  
                 && !HPTE_VALID(HPTE(spapr->htab, index))) {
  
              CLEAN_HPTE(HPTE(spapr->htab, index));
  
              index++;
  
              examined++;
  
          }
  
  
  
          if (index > chunkstart) {
  
              int n_valid = invalidstart - chunkstart;
  
              int n_invalid = index - invalidstart;
  
  
  
              qemu_put_be32(f, chunkstart);
  
              qemu_put_be16(f, n_valid);
  
              qemu_put_be16(f, n_invalid);
  
              qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
  
                              HASH_PTE_SIZE_64 * n_valid);
  
              sent += index - chunkstart;
  
  
  
              if (!final && (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
  
                  break;
  
              }
  
          }
  
  
  
          if (examined >= htabslots) {
  
              break;
  
          }
  
  
  
          if (index >= htabslots) {
  
              assert(index == htabslots);
  
              index = 0;
  
          }
  
      } while ((examined < htabslots) && (!qemu_file_rate_limit(f) || final));
  
  
  
      if (index >= htabslots) {
  
          assert(index == htabslots);
  
          index = 0;
  
      }
  
  
  
      spapr->htab_save_index = index;
  
  
  
      return (examined >= htabslots) && (sent == 0) ? 1 : 0;
  
  }
  