static capptr::Chunk reserve()

in src/backend/backend.h [125:201]


    static capptr::Chunk<void> reserve(
      AddressSpaceManager<PAL>& global, LocalState* local_state, size_t size)
    {
#ifdef SNMALLOC_META_PROTECTED
      constexpr auto MAX_CACHED_SIZE =
        is_meta ? LOCAL_CACHE_META_BLOCK : LOCAL_CACHE_BLOCK;
#else
      constexpr auto MAX_CACHED_SIZE = LOCAL_CACHE_BLOCK;
#endif

      capptr::Chunk<void> p;
      if ((local_state != nullptr) && (size <= MAX_CACHED_SIZE))
      {
#ifdef SNMALLOC_META_PROTECTED
        auto& local = is_meta ? local_state->local_meta_address_space :
                                local_state->local_address_space;
#else
        auto& local = local_state->local_address_space;
#endif

        p = local.template reserve_with_left_over<PAL, Pagemap>(
          local_state, size);
        if (p != nullptr)
        {
          return p;
        }

        auto refill_size = LOCAL_CACHE_BLOCK;
        auto refill =
          global.template reserve<false, Pagemap>(local_state, refill_size);
        if (refill == nullptr)
          return nullptr;

#ifdef SNMALLOC_META_PROTECTED
        if (is_meta)
        {
          refill = sub_range(refill, LOCAL_CACHE_BLOCK, LOCAL_CACHE_META_BLOCK);
          refill_size = LOCAL_CACHE_META_BLOCK;
        }
#endif
        PAL::template notify_using<NoZero>(refill.unsafe_ptr(), refill_size);
        local.template add_range<PAL, Pagemap>(
          local_state, refill, refill_size);

        // This should succeed
        return local.template reserve_with_left_over<PAL, Pagemap>(
          local_state, size);
      }

#ifdef SNMALLOC_META_PROTECTED
      // During start up we need meta-data before we have a local allocator
      // This code protects that meta-data with randomisation, and guard pages.
      if (local_state == nullptr && is_meta)
      {
        size_t rsize = bits::max(OS_PAGE_SIZE, bits::next_pow2(size));
        size_t size_request = rsize * 64;

        p = global.template reserve<false, Pagemap>(local_state, size_request);
        if (p == nullptr)
          return nullptr;

        p = sub_range(p, size_request, rsize);

        PAL::template notify_using<NoZero>(p.unsafe_ptr(), rsize);
        return p;
      }

      // This path does not apply any guard pages to very large
      // meta data requests.  There are currently no meta data-requests
      // this large.  This assert checks for this assumption breaking.
      SNMALLOC_ASSERT(!is_meta);
#endif

      p = global.template reserve_with_left_over<true, Pagemap>(
        local_state, size);
      return p;
    }