chromium/third_party/ipcz/src/ipcz/node_link_memory.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ipcz/node_link_memory.h"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <utility>

#include "ipcz/buffer_id.h"
#include "ipcz/driver_memory.h"
#include "ipcz/fragment_descriptor.h"
#include "ipcz/ipcz.h"
#include "ipcz/link_side.h"
#include "ipcz/node.h"
#include "ipcz/node_link.h"
#include "third_party/abseil-cpp/absl/base/macros.h"
#include "third_party/abseil-cpp/absl/numeric/bits.h"
#include "third_party/abseil-cpp/absl/synchronization/mutex.h"
#include "util/log.h"
#include "util/ref_counted.h"

namespace ipcz {

namespace {

// Fixed allocation size for each NodeLink's primary shared buffer. (128 kB)
constexpr size_t kPrimaryBufferSize =;

// The front of the primary buffer is reserved for special current and future
// uses which require synchronous availability throughout a link's lifetime.
constexpr size_t kPrimaryBufferReservedHeaderSize =;

// NodeLinkMemory may expand its BufferPool's capacity for each fragment size
// as needed. All newly allocated buffers for this purpose must be a multiple of
// kBlockAllocatorPageSize. More specifically, a new buffer allocation for
// fragment size `n` will be the smallest multiple of kBlockAllocatorPageSize
// which can still fit at least kMinBlockAllocatorCapacity blocks of size `n`.
constexpr size_t kBlockAllocatorPageSize =;

// The minimum number of blocks which new BlockAllocator buffers must support.
// See comments on kBlockAllocatorPageSize above.
constexpr size_t kMinBlockAllocatorCapacity =;

// The maximum total BlockAllocator capacity to automatically reserve for any
// given fragment size within the BufferPool. This is not a hard cap on capacity
// per fragment size, but it sets a limit on how large the pool will grow
// automatically in response to failed allocation requests.
constexpr size_t kMaxBlockAllocatorCapacityPerFragmentSize =;

// The minimum fragment size (in bytes) to support with dedicated BufferPool
// capacity. All fragment sizes are powers of two. Fragment allocations below
// this size are rounded up to this size.
constexpr size_t kMinFragmentSize =;

// The maximum fragment size to support with dedicated BlockAllocator capacity
// within the BufferPool. Allocations beyond this size must fail or fall back
// onto a different allocation scheme which does not use a BlockAllocator.
constexpr size_t kMaxFragmentSizeForBlockAllocation =;

// The minimum fallback fragment size to attempt for best-effort allocations
// when the requested size cannot be accommodated.
constexpr size_t kMinBestEffortFallbackBlockSize =;

// The number of fixed RouterLinkState locations in the primary buffer. This
// limits the maximum number of initial portals supported by the ConnectNode()
// API. Note that these states reside in a fixed location at the end of the
// reserved block.
InitialRouterLinkStateArray;
static_assert;

struct IPCZ_ALIGN(8) PrimaryBufferHeader {};

static_assert;

constexpr size_t kPrimaryBufferHeaderPaddingSize =;

// Computes the byte offset of one address from another.
uint32_t ToOffset(void* ptr, void* base) {}

size_t GetBlockSizeForFragmentSize(size_t fragment_size) {}

}  // namespace

// This structure always sits at offset 0 in the primary buffer and has a fixed
// layout according to the NodeLink's agreed upon protocol version. This is the
// layout for version 0 (currently the only version.)
struct IPCZ_ALIGN(8) NodeLinkMemory::PrimaryBuffer {};

NodeLinkMemory::NodeLinkMemory(Ref<Node> node,
                               LinkSide side,
                               const Features& remote_features,
                               DriverMemoryMapping primary_buffer_memory)
    :{}

NodeLinkMemory::~NodeLinkMemory() = default;

void NodeLinkMemory::SetNodeLink(Ref<NodeLink> link) {}

// static
DriverMemoryWithMapping NodeLinkMemory::AllocateMemory(
    const IpczDriver& driver) {}

// static
Ref<NodeLinkMemory> NodeLinkMemory::Create(Ref<Node> node,
                                           LinkSide side,
                                           const Features& remote_features,
                                           DriverMemoryMapping memory) {}

BufferId NodeLinkMemory::AllocateNewBufferId() {}

SublinkId NodeLinkMemory::AllocateSublinkIds(size_t count) {}

FragmentRef<RouterLinkState> NodeLinkMemory::GetInitialRouterLinkState(
    size_t i) {}

Fragment NodeLinkMemory::GetFragment(const FragmentDescriptor& descriptor) {}

bool NodeLinkMemory::AddBlockBuffer(BufferId id,
                                    size_t block_size,
                                    DriverMemoryMapping mapping) {}

Fragment NodeLinkMemory::AllocateFragment(size_t size) {}

Fragment NodeLinkMemory::AllocateFragmentBestEffort(size_t size) {}

bool NodeLinkMemory::FreeFragment(const Fragment& fragment) {}

FragmentRef<RouterLinkState> NodeLinkMemory::TryAllocateRouterLinkState() {}

void NodeLinkMemory::AllocateRouterLinkState(RouterLinkStateCallback callback) {}

void NodeLinkMemory::WaitForBufferAsync(
    BufferId id,
    BufferPool::WaitForBufferCallback callback) {}

bool NodeLinkMemory::CanExpandBlockCapacity(size_t block_size) {}

void NodeLinkMemory::RequestBlockCapacity(
    size_t block_size,
    RequestBlockCapacityCallback callback) {}

void NodeLinkMemory::OnCapacityRequestComplete(size_t block_size,
                                               bool success) {}

FragmentRef<RouterLinkState> NodeLinkMemory::InitializeRouterLinkStateFragment(
    const Fragment& fragment) {}

}  // namespace ipcz