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)