34#include <tdetempfile.h>
37#include "kvmallocator.h"
42struct KVMAllocator::Block
51class KVMAllocatorPrivate
56 TQMap<off_t, KVMAllocator::Block> used_blocks;
57 TQMap<off_t, KVMAllocator::Block> free_blocks;
65 d =
new KVMAllocatorPrivate;
88 d->tempfile =
new KTempFile(TQString::null,
"vmdata");
89 d->tempfile->unlink();
92 TQMap<off_t,KVMAllocator::Block>::iterator it;
93 it = d->free_blocks.begin();
94 while (it != d->free_blocks.end())
96 if (it.data().size > _size)
98 Block &free_block = it.data();
100 kdDebug(180)<<
"VM alloc: using block from free list "<<(long)free_block.start<<
" size ="<<(
long)free_block.size<<
" request = "<<_size<<
endl;
101 block.start = free_block.start;
102 block.length = _size;
103 block.size = (_size + KVM_ALIGN) & ~KVM_ALIGN;
105 free_block.size -= block.size;
106 free_block.start += block.size;
107 if (!free_block.size)
108 d->free_blocks.remove(it);
109 it = d->used_blocks.replace(block.start, block);
118 block.start = d->max_length;
119 block.length = _size;
120 block.size = (_size + KVM_ALIGN) & ~KVM_ALIGN;
122 kdDebug(180)<<
"VM alloc: using new block "<<(long)block.start<<
" size ="<<(
long)block.size<<
" request = "<<_size<<
endl;
123 it = d->used_blocks.replace(block.start, block);
124 d->max_length += block.size;
134 Block block = *block_p;
137 kdDebug(180)<<
"VM free: Block "<<(long)block.start<<
" is still mmapped!"<<
endl;
140 TQMap<off_t,KVMAllocator::Block>::iterator it;
141 it = d->used_blocks.find(block.start);
142 if (it == d->used_blocks.end())
144 kdDebug(180)<<
"VM free: Block "<<(long)block.start<<
" is not allocated."<<
endl;
147 d->used_blocks.remove(it);
148 it = d->free_blocks.replace(block.start, block);
149 TQMap<off_t,KVMAllocator::Block>::iterator before = it;
151 if (before != d->free_blocks.end())
153 Block &block_before = before.data();
154 if ((block_before.start + off_t(block_before.size)) == block.start)
157 kdDebug(180) <<
"VM merging: Block "<< (long)block_before.start<<
158 " with "<< (
long)block.start<<
" (before)" <<
endl;
159 block.size += block_before.size;
160 block.start = block_before.start;
162 d->free_blocks.remove(before);
166 TQMap<off_t,KVMAllocator::Block>::iterator after = it;
168 if (after != d->free_blocks.end())
170 Block &block_after = after.data();
171 if ((block.start + off_t(block.size)) == block_after.start)
174 kdDebug(180) <<
"VM merging: Block "<< (long)block.start<<
175 " with "<< (
long)block_after.start<<
" (after)" <<
endl;
176 block.size += block_after.size;
178 d->free_blocks.remove(after);
189 (void)
copyBlock(dest, src, _offset, length);
196 lseek(d->tempfile->handle(), src->start+_offset, SEEK_SET);
198 length = src->length - _offset;
201 char *buf = (
char *) dest;
204 int n = read(d->tempfile->handle(), buf+done, to_go);
225 (void)
copyBlock(dest, src, _offset, length);
232 lseek(d->tempfile->handle(), dest->start+_offset, SEEK_SET);
234 length = dest->length - _offset;
237 char *buf = (
char *) src;
240 int n = write(d->tempfile->handle(), buf+done, to_go);
241 if (n <= 0)
return false;
258 void *result = mmap(0, block->length, PROT_READ| PROT_WRITE,
259 MAP_SHARED, d->tempfile->handle(), block->start);
260 block->mmap = result;
272 munmap((
char *)block->mmap, block->length);
The KTempFile class creates and opens a unique file for temporary use.
void free(Block *block)
Free a virtual memory block.
KVMAllocator()
Create a KVMAllocator.
~KVMAllocator()
Destruct the KVMAllocator and release all memory.
void * map(Block *block)
Map a virtual memory block in memory.
Block * allocate(size_t _size)
Allocate a virtual memory block.
bool copyBlock(void *dest, Block *src, int _offset=0, size_t length=0)
Copy length bytes from _offset in the virtual memory block src to normal memory at address *dest.
void copy(void *dest, Block *src, int _offset=0, size_t length=0) TDE_DEPRECATED
Copy data from a virtual memory block to normal memory.
void unmap(Block *block)
Unmap a virtual memory block.
kndbgstream & endl(kndbgstream &s)
Does nothing.