20 #include "pedigree/kernel/utilities/MemoryPool.h" 21 #include "pedigree/kernel/LockGuard.h" 22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 24 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 25 #include "pedigree/kernel/utilities/assert.h" 26 #include "pedigree/kernel/utilities/utility.h" 28 static void map(uintptr_t location)
31 #ifdef KERNEL_NEEDS_ADDRESS_SPACE_SWITCH 37 void *page =
page_align(reinterpret_cast<void *>(location));
40 physical_uintptr_t phys =
47 #ifdef KERNEL_NEEDS_ADDRESS_SPACE_SWITCH 52 static bool unmap(uintptr_t location)
55 #ifdef KERNEL_NEEDS_ADDRESS_SPACE_SWITCH 61 void *page =
page_align(reinterpret_cast<void *>(location));
66 physical_uintptr_t phys = 0;
73 #ifdef KERNEL_NEEDS_ADDRESS_SPACE_SWITCH 80 MemoryPoolPressureHandler::MemoryPoolPressureHandler(
MemoryPool *pool)
85 MemoryPoolPressureHandler::~MemoryPoolPressureHandler()
89 const String MemoryPoolPressureHandler::getMemoryPressureDescription()
91 return String(
"MemoryPool: freeing unused pages");
96 return m_Pool->trim();
99 MemoryPool::MemoryPool()
102 m_Condition(), m_Lock(),
104 m_BufferSize(1024), m_BufferCount(0), m_Pool(
"memory-pool"),
105 m_bInitialised(
false), m_AllocBitmap(), m_PressureHandler(
this)
109 MemoryPool::MemoryPool(
const char *poolName)
112 m_Condition(), m_Lock(),
114 m_BufferSize(1024), m_BufferCount(0), m_Pool(poolName),
115 m_bInitialised(
false), m_AllocBitmap(), m_PressureHandler(
this)
119 MemoryPool::~MemoryPool()
122 m_bInitialised =
false;
124 m_Condition.broadcast();
137 if (!poolSize || !bufferSize ||
142 if ((bufferSize & (bufferSize - 1)))
146 while (powerOf2 < bufferSize)
151 bufferSize = powerOf2;
154 m_BufferSize = bufferSize;
157 "MemoryPool: allocating memory pool '" 158 << m_Pool.name() <<
"', " <<
Dec << ((poolSize * 4096) / 1024) <<
Hex 159 <<
"K. Buffer size is " << m_BufferSize <<
".");
166 m_BufferCount = (poolSize * 0x1000) / bufferSize;
171 MemoryPressureManager::HighestPriority, &m_PressureHandler);
181 return allocateDoer(
true);
189 return allocateDoer(
false);
199 size_t poolSize = m_Pool.size();
200 size_t nBuffers = poolSize / m_BufferSize;
201 uintptr_t poolBase =
reinterpret_cast<uintptr_t
>(m_Pool.virtualAddress());
216 if (result.hasError())
232 n = m_AllocBitmap.getFirstClear();
234 m_AllocBitmap.set(n);
239 uintptr_t result = poolBase + (n * 0x1000);
260 size_t n = (buffer -
reinterpret_cast<uintptr_t
>(m_Pool.virtualAddress())) /
262 m_AllocBitmap.clear(n);
269 size_t poolSize = m_Pool.size();
270 size_t nBuffers = poolSize / m_BufferSize;
271 uintptr_t poolBase =
reinterpret_cast<uintptr_t
>(m_Pool.virtualAddress());
278 for (
size_t n = 0; n < nBuffers; ++n)
280 if (!m_AllocBitmap.test(n))
282 uintptr_t page = poolBase + (n * 0x1000);
283 for (
size_t off = 0; off < m_BufferSize;
286 if (unmap(page + off))
297 for (
size_t n = 0, m = 0; n < nBuffers; n += N, ++m)
299 if (m_AllocBitmap.test(n))
303 for (
size_t y = 1; y < N; ++y)
305 if (m_AllocBitmap.test(n + y))
315 uintptr_t page = poolBase + (m * 0x1000);
virtual void unmap(void *virtualAddress)=0
static size_t getPageSize() PURE
static PhysicalMemoryManager & instance()
static const size_t virtualOnly
virtual void getMapping(void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags)=0
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
virtual bool isMapped(void *virtualAddress)=0
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
static ProcessorInformation & information()
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)
bool trim()
Trims the pool, freeing pages that are not otherwise in use.
static const size_t Write
static const size_t KernelMode
bool initialise(size_t poolSize, size_t bufferSize=1024)
uintptr_t allocateDoer(bool canBlock)
Allocation doer.
void free(uintptr_t buffer)
Frees an allocated buffer, allowing it to be used elsewhere.
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)=0
EXPORTED_PUBLIC void * page_align(void *p) PURE
virtual void freePage(physical_uintptr_t page)=0
void registerHandler(size_t prio, MemoryPressureHandler *pHandler)