void IOBuf::releaseStorage(HeapStorage* storage, uint16_t freeFlags) noexcept {
  CHECK_EQ(storage->prefix.magic, static_cast<uint16_t>(kHeapMagic));

  // Use relaxed memory order here.  If we are unlucky and happen to get
  // out-of-date data the compare_exchange_weak() call below will catch
  // it and load new data with memory_order_acq_rel.
  auto flags = storage->prefix.flags.load(std::memory_order_acquire);
  DCHECK_EQ((flags & freeFlags), freeFlags);

  while (true) {
    auto newFlags = uint16_t(flags & ~freeFlags);
    if (newFlags == 0) {
      // save the size
      size_t size = storage->prefix.size;
      // The storage space is now unused.  Free it.
      storage->prefix.HeapPrefix::~HeapPrefix();
      if (FOLLY_LIKELY(size)) {
        if (io_buf_free_cb) {
          io_buf_free_cb(storage, size);
        }
        sizedFree(storage, size);
      } else {
        free(storage);
      }
      return;
    }

    // This storage segment still contains portions that are in use.
    // Just clear the flags specified in freeFlags for now.
    auto ret = storage->prefix.flags.compare_exchange_weak(
        flags, newFlags, std::memory_order_acq_rel);
    if (ret) {
      // We successfully updated the flags.
      return;
    }

    // We failed to update the flags.  Some other thread probably updated them
    // and cleared some of the other bits.  Continue around the loop to see if
    // we are the last user now, or if we need to try updating the flags again.
  }
}
void IOBuf::releaseStorage(HeapStorage* storage, uint16_t freeFlags) noexcept {
  CHECK_EQ(storage->prefix.magic, static_cast<uint16_t>(kHeapMagic));

   
   
   
  auto flags = storage->prefix.flags.load(std::memory_order_acquire);
  DCHECK_EQ((flags & freeFlags), freeFlags);

  while (true) {
    auto newFlags = uint16_t(flags & ~freeFlags);
    if (newFlags == 0) {
       
      size_t size = storage->prefix.size;
       
      storage->prefix.HeapPrefix::~HeapPrefix();
      if (FOLLY_LIKELY(size)) {
        if (io_buf_free_cb) {
          io_buf_free_cb(storage, size);
        }
        sizedFree(storage, size);
      } else {
        free(storage);
      }
      return;
    }

     
     
    auto ret = storage->prefix.flags.compare_exchange_weak(
        flags, newFlags, std::memory_order_acq_rel);
    if (ret) {
       
      return;
    }

     
     
     
  }
}