blob: 89fc2f82d71aeda2ca62d81b3f1ae3b2244f536b [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_PHYS_INCLUDE_PHYS_ZBITL_ALLOCATION_H_
#define ZIRCON_KERNEL_PHYS_INCLUDE_PHYS_ZBITL_ALLOCATION_H_
#include <lib/fitx/result.h>
#include <lib/zbitl/storage-traits.h>
#include <ktl/string_view.h>
#include "allocation.h"
// This matches the zbitl::View::CopyStorageItem allocator signature.
fitx::result<ktl::string_view, Allocation> ZbitlScratchAllocator(size_t size);
template <>
struct zbitl::StorageTraits<Allocation> {
using Storage = Allocation;
using SpanTraits = zbitl::StorageTraits<ktl::span<ktl::byte>>;
// An instance represents a failure mode of being out of memory.
using error_type = SpanTraits::error_type;
using payload_type = SpanTraits::payload_type;
static std::string_view error_string(error_type error) { return "out of memory"; }
static fitx::result<error_type, uint32_t> Capacity(const Storage& storage) {
return fitx::ok(static_cast<uint32_t>(storage.size_bytes()));
}
static fitx::result<error_type> EnsureCapacity(Storage& storage, uint32_t capacity_bytes) {
if (capacity_bytes > storage.size_bytes()) {
fbl::AllocChecker ac;
storage.Resize(ac, capacity_bytes);
if (!ac.check()) {
return fitx::error{error_type{}};
}
}
return fitx::ok();
}
static fitx::result<error_type, payload_type> Payload(const Storage& storage, uint32_t offset,
uint32_t length) {
auto span = storage.data();
return SpanTraits::Payload(span, offset, length);
}
template <typename U, bool LowLocality>
static auto Read(const Storage& storage, payload_type payload, uint32_t length) {
auto span = storage.data();
return SpanTraits::template Read<U, LowLocality>(span, payload, length);
}
static fitx::result<error_type> Write(Storage& storage, uint32_t offset, zbitl::ByteView data) {
auto span = storage.data();
return SpanTraits::Write(span, offset, data);
}
static fitx::result<error_type, void*> Write(Storage& storage, uint32_t offset, uint32_t length) {
auto span = storage.data();
return SpanTraits::Write(span, offset, length);
}
static fitx::result<error_type, Storage> Create(Storage& old, uint32_t size,
uint32_t initial_zero_size) {
fbl::AllocChecker ac;
Storage new_storage = Allocation::New(ac, old.type(), size, old.alignment());
if (!ac.check()) {
return fitx::error{error_type{}};
}
if (initial_zero_size > 0) {
ZX_DEBUG_ASSERT(initial_zero_size <= size);
memset(new_storage.get(), 0, initial_zero_size);
}
return fitx::ok(std::move(new_storage));
}
};
#endif // ZIRCON_KERNEL_PHYS_INCLUDE_PHYS_ZBITL_ALLOCATION_H_