• 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 
42 struct 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 
51 class KVMAllocatorPrivate
52 {
53 public:
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 
63 KVMAllocator::KVMAllocator()
64 {
65  d = new KVMAllocatorPrivate;
66  d->tempfile = 0;
67  d->max_length = 0;
68 }
69 
73 KVMAllocator::~KVMAllocator()
74 {
75  delete d->tempfile;
76  delete d;
77 }
78 
83 KVMAllocator::Block *
84 KVMAllocator::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 
131 void
132 KVMAllocator::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 
186 void
187 KVMAllocator::copy(void *dest, Block *src, int _offset, size_t length)
188 {
189  (void) copyBlock(dest, src, _offset, length);
190 }
191 
192 bool
193 KVMAllocator::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 
222 void
223 KVMAllocator::copy(Block *dest, void *src, int _offset, size_t length)
224 {
225  (void) copyBlock(dest, src, _offset, length);
226 }
227 
228 bool
229 KVMAllocator::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 
252 void *
253 KVMAllocator::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 
267 void
268 KVMAllocator::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 }
KVMAllocator::KVMAllocator
KVMAllocator()
Create a KVMAllocator.
Definition: kvmallocator.cpp:63
KVMAllocator::allocate
Block * allocate(size_t _size)
Allocate a virtual memory block.
Definition: kvmallocator.cpp:84
KVMAllocator::free
void free(Block *block)
Free a virtual memory block.
Definition: kvmallocator.cpp:132
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
KTempFile
The KTempFile class creates and opens a unique file for temporary use.
Definition: tdetempfile.h:55
KVMAllocator::unmap
void unmap(Block *block)
Unmap a virtual memory block.
Definition: kvmallocator.cpp:268
KVMAllocator::map
void * map(Block *block)
Map a virtual memory block in memory.
Definition: kvmallocator.cpp:253
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583
KVMAllocator::copy
void copy(void *dest, Block *src, int _offset=0, size_t length=0) KDE_DEPRECATED
Copy data from a virtual memory block to normal memory.
Definition: kvmallocator.cpp:187
KVMAllocator::~KVMAllocator
~KVMAllocator()
Destruct the KVMAllocator and release all memory.
Definition: kvmallocator.cpp:73

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.