Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

[3e4acc]: libkwave / MemoryManager.h Maximize Restore History

Download this file

MemoryManager.h    282 lines (224 with data), 8.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/***************************************************************************
MemoryManager.h - Manager for virtual and physical memory
-------------------
begin : Wed Aug 08 2001
copyright : (C) 2000 by Thomas Eschenbacher
email : Thomas.Eschenbacher@gmx.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _MEMORY_MANAGER_H_
#define _MEMORY_MANAGER_H_
#include "config.h"
#include <stddef.h> // for size_t
#include <QDir>
#include <QHash>
#include <QMutex>
#include <QString>
#include <kdemacros.h>
#include "libkwave/LRU_Cache.h"
class SwapFile;
namespace Kwave {
/** handle for memory manager */
typedef int Handle;
class MemoryManager
{
public:
/** Constructor */
MemoryManager() KDE_NO_EXPORT;
/** Destructor */
virtual ~MemoryManager() KDE_NO_EXPORT;
/** Closes the memory manager and does cleanups at program shutdown */
void close() KDE_NO_EXPORT;
/**
* Gets a block of memory, either in physical memory or in a swap file
* if there is not enough physical memory. If there is not enough
* memory at all, the return value will be a null pointer.
*
* @param size number of bytes to allocate
* @return handle of a storage object, to be used to be mapped
* into physical memory through map() or zero if out of memory
*/
Kwave::Handle allocate(size_t size) KDE_EXPORT;
/**
* Resizes a block of memory to a new size. If the block will no longer
* fit in physical memory, the block will be swapped out to a page file.
*
* @param handle handle of the existing block
* @param size new size of the block in bytes
* @return true if successful, false if out of memory or if the
* block is currently in use
*/
bool resize(Kwave::Handle handle, size_t size) KDE_EXPORT;
/**
* Frees a block of memory that has been previously allocated with the
* allocate() function.
*
* @param handle reference to the handle to the block to be freed. The
* handle will be set to zero afterwards.
*/
void free(Kwave::Handle &handle) KDE_EXPORT;
/**
* Sets the limit of physical memory that can be used.
* @param mb number of whole megabytes of the limit
*/
void setPhysicalLimit(unsigned int mb) KDE_EXPORT;
/**
* Sets the limit of virtual memory that can be used.
* @param mb number of whole megabytes of the limit
*/
void setVirtualLimit(unsigned int mb) KDE_EXPORT;
/**
* Sets the directory where swap files should be stored
* @param dir directory
*/
void setSwapDirectory(const QString &dir) KDE_EXPORT;
/**
* Sets the limit of memory that can be used for undo/redo.
* @param mb number of whole megabytes of the limit
*/
void setUndoLimit(unsigned int mb) KDE_EXPORT;
/**
* Returns the limit of memory that can be used for undo/redo
* in units of whole megabytes
*/
unsigned int undoLimit() const KDE_EXPORT;
/**
* Returns the total amount of theoretically available physical
* memory, as the minimum of the totally installed memory and
* ulimit settings.
*/
unsigned int totalPhysical() KDE_EXPORT;
/**
* Returns the global instance of the memory manager from the
* KwaveApp.
*/
static MemoryManager &instance() KDE_EXPORT;
/**
* Map a portion of memory and return the physical address.
*
* @param handle handle of the object that identifies the
* memory block
* @return pointer to the mapped area or null if failed
*/
void *map(Kwave::Handle handle) KDE_EXPORT;
/**
* Unmap a memory area, previously mapped with map()
*
* @param handle handle of a mapped block mapped with map()
*/
void unmap(Kwave::Handle handle) KDE_EXPORT;
/**
* Read from a memory block into a buffer
*
* @param handle handle of the object that identifies the
* memory block
* @param offset offset within the object [bytes]
* @param buffer pointer to a buffer that is to be filled
* @param length number of bytes to read
* @return number of read bytes or < 0 if failed
*/
int readFrom(Kwave::Handle handle, unsigned int offset,
void *buffer, unsigned int length) KDE_EXPORT;
/**
* Write a buffer into a memory block
*
* @param handle handle of the object that identifies the
* memory block
* @param offset offset within the object [bytes]
* @param buffer pointer to a buffer that is to be written
* @param length number of bytes to write
* @return number of written bytes or < 0 if failed
*/
int writeTo(Kwave::Handle handle, unsigned int offset,
const void *buffer, unsigned int length) KDE_EXPORT;
protected:
/** returns the currently allocated physical memory */
size_t physicalUsed() KDE_NO_EXPORT;
/** returns the currently allocated virtual memory */
size_t virtualUsed() KDE_NO_EXPORT;
/** returns a new swap file name */
QString nextSwapFileName(Kwave::Handle handle) KDE_NO_EXPORT;
/** convert a physical memory block into a new larger pagefile */
bool convertToVirtual(Kwave::Handle handle, size_t new_size) KDE_NO_EXPORT;
/** convert a swapfile into a physical memory block */
bool convertToPhysical(Kwave::Handle handle, size_t new_size) KDE_NO_EXPORT;
/** tries to allocate physical memory */
Kwave::Handle allocatePhysical(size_t size) KDE_NO_EXPORT;
/** tries to convert to physical RAM */
void tryToMakePhysical(Kwave::Handle handle);
/**
* Tries to allocate virtual memory
*
* @param size number of bytes to allocate
* @return handle of a SwapFile object or zero if failed
*/
Kwave::Handle allocateVirtual(size_t size) KDE_NO_EXPORT;
private:
/**
* get a new handle.
* @note the handle does not need to be freed later
* @return a non-zero handle or zero if all handles are in use
*/
Kwave::Handle newHandle();
/**
* try to make some room in the physical memory area by kicking
* out the oldest entries to swap if possible.
*
* @param size number of bytes to free
* @return true if successful, false if failed
*/
bool freePhysical(size_t size);
/**
* Makes sure that the object is not a swapfile in cache. If so,
* it will be unmapped and moved to the m_unmapped_swap list.
*
* @param handle handle of a block in m_cached_swap
*/
void unmapFromCache(Kwave::Handle handle) KDE_NO_EXPORT;
/** dump current state (for debugging) */
void dump(const char *function);
private:
typedef struct physical_memory_t {
void *m_data; /**< pointer to the physical memory */
size_t m_size; /**< size of the block */
int m_mapcount; /**< counter for mmap */
} physical_memory_t;
private:
/** currently allocated amount of physical memory */
unsigned int m_physical_allocated;
/** limit of the physical memory */
unsigned int m_physical_limit;
/** currently allocated amount of physical memory */
unsigned int m_virtual_allocated;
/** limit of the virtual memory, 0 = disabled */
unsigned int m_virtual_limit;
/** path where to store swap files */
QDir m_swap_dir;
/** limit of memory available for undo/redo */
unsigned int m_undo_limit;
/** map of objects in physical memory */
Kwave::LRU_Cache<Kwave::Handle, physical_memory_t> m_physical;
/** map of swapfile objects that are not mapped into memory */
QHash<Kwave::Handle, SwapFile *> m_unmapped_swap;
/** map of swapfile objects that are already mapped into memory */
QHash<Kwave::Handle, SwapFile *> m_mapped_swap;
/**
* cache for swapfiles that have been recently used, are mapped
* and get unmapped if the queue is full. The queue will be used
* as a FIFO with fixed size.
*/
QHash<Kwave::Handle, SwapFile *> m_cached_swap;
/** mutex for ensuring exclusive access */
QMutex m_lock;
/** last used handle */
static Kwave::Handle m_last_handle;
};
}
#endif /* _MEMORY_MANAGER_H_ */