The Pedigree Project 0.1
MemoryPressureManager.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef MEMORY_PRESSURE_MANAGER_H
21#define MEMORY_PRESSURE_MANAGER_H
22#include "pedigree/kernel/Atomic.h"
23#include "pedigree/kernel/Spinlock.h"
24#include "pedigree/kernel/compiler.h"
25#include "pedigree/kernel/process/WaitQueue.h"
26#include "pedigree/kernel/processor/types.h"
27#include "pedigree/kernel/utilities/new"
28
29#include <config.h>
30
32#define MAX_MEMPRESSURE_PRIORITY 16
33
37class EXPORTED_PUBLIC MemoryPressureHandler {
38 public:
40 virtual ~MemoryPressureHandler();
41
46 virtual const char* getMemoryPressureDescription() = 0;
47
53 virtual bool compact() = 0;
54
55 private:
56 friend class MemoryPressureManager;
57
58 MemoryPressureHandler* m_pPrevious;
59 MemoryPressureHandler* m_pNext;
60 size_t m_Priority;
61 size_t m_RegistrationSequence;
62 bool m_bRegistered;
63 bool m_bRemoving;
64
65#if THREADS
68 const void* m_pCallbackOwner;
69 WaitQueue m_CallbackWaiters;
70#endif
71};
72
80class EXPORTED_PUBLIC MemoryPressureManager {
81 public:
84
85 const static size_t HighestPriority = 0;
86 const static size_t HighPriority = MAX_MEMPRESSURE_PRIORITY / 3;
87 const static size_t MediumPriority = MAX_MEMPRESSURE_PRIORITY / 2;
88 const static size_t LowPriority = (MAX_MEMPRESSURE_PRIORITY * 2) / 3;
89 const static size_t LowestPriority = MAX_MEMPRESSURE_PRIORITY - 1;
90
91 static MemoryPressureManager& instance() {
92 return m_Instance;
93 }
94
95 static size_t getHighWatermark() {
96 // Once the system has only this or less pages free, we begin
97 // doing compacts. We do not want to wait until the system is
98 // actually out of memory, as some compact mechanisms require
99 // allocating memory.
100 return 16;
101 }
102
103 static size_t getLowWatermark() {
104 // Caches can begin voluntarily evicting cache pages at this mark.
105 // Should no action be taken, the system will take over forcefully
106 // at the high water mark.
107 return 32;
108 }
109
119 bool compact();
120
126 bool compactingForCurrentExecution() const;
127
131 void registerHandler(size_t prio, MemoryPressureHandler* pHandler);
132
136 void removeHandler(MemoryPressureHandler* pHandler);
137
138 private:
139 static MemoryPressureManager m_Instance;
140
141 Spinlock m_Lock;
142 MemoryPressureHandler* m_Handlers[MAX_MEMPRESSURE_PRIORITY];
143 MemoryPressureHandler* m_HandlerTails[MAX_MEMPRESSURE_PRIORITY];
144 size_t m_NextRegistrationSequence;
145 Atomic<bool> m_bCompacting;
146 const void* m_pCompactOwner;
147#if THREADS
148 WaitQueue m_CompactWaiters;
149#endif
150};
151
152#endif
virtual bool compact()=0
virtual const char * getMemoryPressureDescription()=0