54  assert_return (0 == (minimum_alignment & (minimum_alignment - 1)), {}); 
 
   55  constexpr int protection = PROT_READ | PROT_WRITE;
 
   56  constexpr int flags = MAP_PRIVATE | MAP_ANONYMOUS;
 
   58  if (bytelength == MEM_ALIGN (bytelength, MINIMUM_HUGEPAGE) && minimum_alignment <= MINIMUM_HUGEPAGE)
 
   60      void *memory = 
mmap (
nullptr, bytelength, protection, flags | MAP_HUGETLB, -1, 0);
 
   61      if (memory != MAP_FAILED)
 
   63          assert_return ((
size_t (memory) & (minimum_alignment - 1)) == 0, {}); 
 
   65          const int mlret = 
mlock (memory, bytelength);
 
   67            printerr (
"%s: mlock(%p,%u) failed: %s\n", __func__, memory, bytelength, 
strerror (
errno));
 
   72  if (bytelength == MEM_ALIGN (bytelength, 
std::max (minimum_alignment, MINIMUM_HUGEPAGE)))
 
   74      static const size_t pagesize = 
sysconf (_SC_PAGESIZE);
 
   75      minimum_alignment = 
std::max (minimum_alignment, MINIMUM_HUGEPAGE);
 
   76      size_t areasize = minimum_alignment - pagesize + bytelength;
 
   77      char *memory = (
char*) 
mmap (
nullptr, areasize, protection, flags, -1, 0);
 
   82          size_t extra = MEM_ALIGN (start, minimum_alignment) - start;
 
   83          if (extra && 
munmap (memory, extra) != 0)
 
   84            printerr (
"%s: munmap(%p,%u) failed: %s\n", __func__, memory, extra, 
strerror (
errno));
 
   88          extra = areasize - 
size_t (areasize / minimum_alignment) * minimum_alignment;
 
   90          if (extra && 
munmap (memory + areasize, extra) != 0)
 
   91            printerr (
"%s: munmap(%p,%u) failed: %s\n", __func__, memory + areasize, extra, 
strerror (
errno));
 
   94          assert_return ((
size_t (memory) & (minimum_alignment - 1)) == 0, {}); 
 
   96          const int mlret = 
mlock (memory, bytelength);
 
   98            printerr (
"%s: mlock(%p,%u) failed: %s\n", __func__, memory, bytelength, 
strerror (
errno));
 
   99          LinuxHugePage::ReleaseF release;
 
  101          if (madvise (memory, areasize, MADV_HUGEPAGE) >= 0)
 
  102            release = &LinuxHugePage::unadvise_munmap_start;
 
  104            release = &LinuxHugePage::munmap_start;
 
  109  if (bytelength == MEM_ALIGN (bytelength, MINIMUM_HUGEPAGE) && minimum_alignment <= MINIMUM_HUGEPAGE)
 
  114          assert_return ((
size_t (memory) & (minimum_alignment - 1)) == 0, {}); 
 
  115          LinuxHugePage::ReleaseF release;
 
  117          if (madvise (memory, bytelength, MADV_HUGEPAGE) >= 0)
 
  118            release = &LinuxHugePage::unadvise_free_start;
 
  120            release = &LinuxHugePage::free_start;
 
  128  assert_return ((
size_t (memory) & (minimum_alignment - 1)) == 0, {}); 
 
 
  145  const uint32          mem_alignment;
 
  147    blob (newblob), mem_alignment (alignment)
 
  151    assert_return ((
size_t (blob->mem()) & (blob->alignment() - 1)) == 0);
 
  152    if (size() >= 1024 * 1024)
 
  153      extents.reserve (1024);
 
  156    area.zero (blob->mem());
 
  162    const size_t s = sum();
 
  163    if (s != blob->size())
 
  164      warning (
"%s:%s: deleting area while bytes are unreleased: %zd", __FILE__, __func__, blob->size() - s);
 
  181    for (
const auto b : extents)
 
  190    ext.zero (blob->mem());
 
  191    ssize_t overlaps_existing = -1, before = -1, after = -1;
 
  192    for (
size_t i = 0; i < extents.size(); i++)
 
  193      if (ext.start == extents[i].start + extents[i].length)
 
  199      else if (ext.start + ext.length == extents[i].start)
 
  205      else if (CHECK_FREE_OVERLAPS &&
 
  206               ext.start + ext.length > extents[i].start &&
 
  207               ext.start < extents[i].start + extents[i].length)
 
  208        overlaps_existing = i;
 
  213        extents[after].length += ext.length;
 
  216            extents[after].length += extents[before].length;
 
  217            extents.erase (extents.begin() + before);
 
  223        extents[before].length += ext.length;
 
  224        extents[before].start = ext.start;
 
  228    extents.push_back (ext);
 
  231  best_fit (
size_t length)
 const 
  234    for (
size_t j = 0; j < extents.size(); j++)
 
  236        const size_t i = extents.size() - 1 - j; 
 
  237        if (
ISLIKELY (length > extents[i].length))
 
  239        if (
ISLIKELY (length == extents[i].length))     
 
  243            ISLIKELY (extents[i].length < extents[candidate].length) or
 
  244            (
ISLIKELY (extents[i].length == extents[candidate].length) and
 
  245             ISLIKELY (extents[i].start < extents[candidate].start)))
 
  255    const uint32 aligned_length = MEM_ALIGN (ext.length, mem_alignment);
 
  257    const ssize_t candidate = best_fit (aligned_length);
 
  261    ext.start = extents[candidate].start;
 
  262    ext.length = aligned_length;
 
  263    if (
UNLIKELY (extents[candidate].length > aligned_length))
 
  265        extents[candidate].start += aligned_length;
 
  266        extents[candidate].length -= aligned_length;
 
  271        extents[candidate] = extents.back();
 
  272        extents.resize (extents.size() - 1);
 
  283          return a.start < b.start;
 
  285        std::sort (extents.begin(), extents.end(), isless_start);
 
  286        for (
size_t i = extents.size() - 1; i > 0; i--)
 
  287          if (extents[i-1].start + extents[i-1].length == extents[i].start) 
 
  289              extents[i-1].length += extents[i].length;
 
  290              extents.erase (extents.begin() + i);