• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
kvmallocator.cpp
1/*
2 This file is part of the KDE libraries
3
4 Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21//----------------------------------------------------------------------------
22//
23// Virtual Memory Allocator
24
25// TODO: Add large file support.
26// TODO: Error reporting. (e.g. disk-full)
27
28#include <unistd.h>
29#include <sys/mman.h>
30
31#include <tqintdict.h>
32#include <tqmap.h>
33
34#include <tdetempfile.h>
35#include <kdebug.h>
36
37#include "kvmallocator.h"
38
39
40#define KVM_ALIGN 4095
41
42struct KVMAllocator::Block
43{
44 off_t start;
45 size_t length; // Requested length
46 size_t size; // Actual size
47 void *mmap;
48};
49
50
51class KVMAllocatorPrivate
52{
53public:
54 KTempFile *tempfile;
55 off_t max_length;
56 TQMap<off_t, KVMAllocator::Block> used_blocks;
57 TQMap<off_t, KVMAllocator::Block> free_blocks;
58};
59
63KVMAllocator::KVMAllocator()
64{
65 d = new KVMAllocatorPrivate;
66 d->tempfile = 0;
67 d->max_length = 0;
68}
69
73KVMAllocator::~KVMAllocator()
74{
75 delete d->tempfile;
76 delete d;
77}
78
83KVMAllocator::Block *
84KVMAllocator::allocate(size_t _size)
85{
86 if (!d->tempfile)
87 {
88 d->tempfile = new KTempFile(TQString::null, "vmdata");
89 d->tempfile->unlink();
90 }
91 // Search in free list
92 TQMap<off_t,KVMAllocator::Block>::iterator it;
93 it = d->free_blocks.begin();
94 while (it != d->free_blocks.end())
95 {
96 if (it.data().size > _size)
97 {
98 Block &free_block = it.data();
99 Block block;
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;
104 block.mmap = 0;
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);
110 return &(it.data());
111 }
112 ++it;
113 }
114
115
116 // Create new block
117 Block block;
118 block.start = d->max_length;
119 block.length = _size;
120 block.size = (_size + KVM_ALIGN) & ~KVM_ALIGN;
121 block.mmap = 0;
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;
125 return &(it.data());
126}
127
131void
132KVMAllocator::free(Block *block_p)
133{
134 Block block = *block_p;
135 if (block.mmap)
136 {
137 kdDebug(180)<<"VM free: Block "<<(long)block.start<<" is still mmapped!"<<endl;
138 return;
139 }
140 TQMap<off_t,KVMAllocator::Block>::iterator it;
141 it = d->used_blocks.find(block.start);
142 if (it == d->used_blocks.end())
143 {
144 kdDebug(180)<<"VM free: Block "<<(long)block.start<<" is not allocated."<<endl;
145 return;
146 }
147 d->used_blocks.remove(it);
148 it = d->free_blocks.replace(block.start, block);
149 TQMap<off_t,KVMAllocator::Block>::iterator before = it;
150 --before;
151 if (before != d->free_blocks.end())
152 {
153 Block &block_before = before.data();
154 if ((block_before.start + off_t(block_before.size)) == block.start)
155 {
156 // Merge blocks.
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;
161 it.data() = block;
162 d->free_blocks.remove(before);
163 }
164 }
165
166 TQMap<off_t,KVMAllocator::Block>::iterator after = it;
167 ++after;
168 if (after != d->free_blocks.end())
169 {
170 Block &block_after = after.data();
171 if ((block.start + off_t(block.size)) == block_after.start)
172 {
173 // Merge blocks.
174 kdDebug(180) << "VM merging: Block "<< (long)block.start<<
175 " with "<< (long)block_after.start<< " (after)" << endl;
176 block.size += block_after.size;
177 it.data() = block;
178 d->free_blocks.remove(after);
179 }
180 }
181}
182
186void
187KVMAllocator::copy(void *dest, Block *src, int _offset, size_t length)
188{
189 (void) copyBlock(dest, src, _offset, length);
190}
191
192bool
193KVMAllocator::copyBlock(void *dest, Block *src, int _offset, size_t length)
194{
195 //kdDebug(180)<<"VM read: seek "<<(long)src->start<<" +"<<_offset<<":"<<length<<endl;
196 lseek(d->tempfile->handle(), src->start+_offset, SEEK_SET);
197 if (length == 0)
198 length = src->length - _offset;
199 int to_go = length;
200 int done = 0;
201 char *buf = (char *) dest;
202 while(to_go > 0)
203 {
204 int n = read(d->tempfile->handle(), buf+done, to_go);
205 if (n <= 0)
206 {
207 if (n < 0)
208 return false; // Error
209 else
210 return true; // End of data
211 }
212 done += n;
213 to_go -= n;
214 }
215 // Done.
216 return true;
217}
218
222void
223KVMAllocator::copy(Block *dest, void *src, int _offset, size_t length)
224{
225 (void) copyBlock(dest, src, _offset, length);
226}
227
228bool
229KVMAllocator::copyBlock(Block *dest, void *src, int _offset, size_t length)
230{
231 //kdDebug(180)<<"VM write: seek "<<(long)dest->start<<" +"<<_offset<< ":" << length << endl;
232 lseek(d->tempfile->handle(), dest->start+_offset, SEEK_SET);
233 if (length == 0)
234 length = dest->length - _offset;
235 int to_go = length;
236 int done = 0;
237 char *buf = (char *) src;
238 while(to_go > 0)
239 {
240 int n = write(d->tempfile->handle(), buf+done, to_go);
241 if (n <= 0) return false; // Error
242 done += n;
243 to_go -= n;
244 }
245 // Done.
246 return true;
247}
248
252void *
253KVMAllocator::map(Block *block)
254{
255 if (block->mmap)
256 return block->mmap;
257
258 void *result = mmap(0, block->length, PROT_READ| PROT_WRITE,
259 MAP_SHARED, d->tempfile->handle(), block->start);
260 block->mmap = result;
261 return block->mmap;
262}
263
267void
268KVMAllocator::unmap(Block *block)
269{
270 // The following cast is necassery for Solaris.
271 // (touch it and die). --Waba
272 munmap((char *)block->mmap, block->length);
273 block->mmap = 0;
274}
KTempFile
The KTempFile class creates and opens a unique file for temporary use.
Definition: tdetempfile.h:56
KVMAllocator::free
void free(Block *block)
Free a virtual memory block.
Definition: kvmallocator.cpp:132
KVMAllocator::KVMAllocator
KVMAllocator()
Create a KVMAllocator.
Definition: kvmallocator.cpp:63
KVMAllocator::~KVMAllocator
~KVMAllocator()
Destruct the KVMAllocator and release all memory.
Definition: kvmallocator.cpp:73
KVMAllocator::map
void * map(Block *block)
Map a virtual memory block in memory.
Definition: kvmallocator.cpp:253
KVMAllocator::allocate
Block * allocate(size_t _size)
Allocate a virtual memory block.
Definition: kvmallocator.cpp:84
KVMAllocator::copyBlock
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.
Definition: kvmallocator.cpp:193
KVMAllocator::copy
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.
Definition: kvmallocator.cpp:187
KVMAllocator::unmap
void unmap(Block *block)
Unmap a virtual memory block.
Definition: kvmallocator.cpp:268
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.