Grok 20.3.2
MemAdvisor.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2026 Grok Image Compression Inc.
3 *
4 * This source code is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License, version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This source code is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Affero General Public License for more details.
12 *
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#pragma once
19
20#include <cstddef>
21#include <cstdint>
22#include <stdexcept>
23
24#ifndef _WIN32
25#include <sys/mman.h>
26#include <unistd.h>
27#endif
28
29#include "IMemAdvisor.h"
30
31namespace grk
32{
33
35{
36private:
37 uint8_t* m_ptr; // Base pointer of the mapped buffer
38 size_t m_len; // Length of the mapped buffer
39 size_t m_initial_offset; // Initial offset applied to virtual offsets
40
41public:
42 MemAdvisor(uint8_t* ptr, size_t len, size_t initial_offset)
43 : m_ptr(ptr), m_len(len), m_initial_offset(initial_offset)
44 {}
45
46 void advise(size_t virtual_offset, size_t length, GrkAccessPattern pattern)
47 {
48 // Adjust virtual offset to physical offset
49 size_t physical_offset = virtual_offset + m_initial_offset;
50 if(physical_offset >= m_len)
51 return;
52 if(length == 0)
53 length = m_len - physical_offset;
54 if(length == 0)
55 return;
56 if(physical_offset + length > m_len)
57 length = m_len - physical_offset;
58
59#ifndef _WIN32
60 long page_size = sysconf(_SC_PAGESIZE);
61 if(page_size <= 0)
62 throw std::runtime_error("Failed to get page size");
63
64 // Skip madvise for small ranges (< one page)
65 if(length < static_cast<size_t>(page_size))
66 return;
67
68 uintptr_t base = reinterpret_cast<uintptr_t>(m_ptr);
69 uintptr_t start = base + physical_offset;
70 uintptr_t end = start + length;
71
72 // Find page-aligned range containing the region
73 uintptr_t aligned_start = start & ~(static_cast<uintptr_t>(page_size) - 1);
74 uintptr_t aligned_end =
75 (end + static_cast<uintptr_t>(page_size) - 1) & ~(static_cast<uintptr_t>(page_size) - 1);
76
77 if(aligned_start >= aligned_end)
78 return;
79
80 size_t advise_len = aligned_end - aligned_start;
81 void* advise_addr = reinterpret_cast<void*>(aligned_start);
82
83 int advice;
84 switch(pattern)
85 {
87 advice = MADV_SEQUENTIAL;
88 break;
90 advice = MADV_RANDOM;
91 break;
93 advice = MADV_NORMAL;
94 break;
96 advice = MADV_DONTNEED;
97 break;
98 default:
99 throw std::runtime_error("Invalid access pattern");
100 }
101
102 if(madvise(advise_addr, advise_len, advice) != 0)
103 {
104 throw std::runtime_error("madvise failed");
105 }
106#endif
107 }
108};
109
110} // namespace grk
void advise(size_t virtual_offset, size_t length, GrkAccessPattern pattern)
Definition MemAdvisor.h:46
size_t m_initial_offset
Definition MemAdvisor.h:39
uint8_t * m_ptr
Definition MemAdvisor.h:37
size_t m_len
Definition MemAdvisor.h:38
MemAdvisor(uint8_t *ptr, size_t len, size_t initial_offset)
Definition MemAdvisor.h:42
ResWindow.
Definition CompressedChunkCache.h:36
GrkAccessPattern
Definition IMemAdvisor.h:24
@ ACCESS_SEQUENTIAL
Definition IMemAdvisor.h:25
@ ACCESS_RANDOM
Definition IMemAdvisor.h:26
@ ACCESS_NORMAL
Definition IMemAdvisor.h:27
@ ACCESS_DONTNEED
Definition IMemAdvisor.h:28