File indexing completed on 2024-04-28 03:53:10
0001 /* 0002 This file is part of the KDE libraries 0003 0004 SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org> 0005 SPDX-FileCopyrightText: 2002 Michael Matz <matz@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 //---------------------------------------------------------------------------- 0010 // 0011 // KDE Memory Allocator 0012 0013 #ifndef KZONEALLOCATOR_P_H 0014 #define KZONEALLOCATOR_P_H 0015 0016 #include <cstddef> // size_t 0017 0018 template<typename T> 0019 class QList; 0020 0021 /** 0022 * \class KZoneAllocator kallocator.h <KZoneAllocator> 0023 * 0024 * Memory allocator for large groups of small objects. 0025 * This should be used for large groups of objects that are created and 0026 * destroyed together. When used carefully for this purpose it is faster 0027 * and more memory efficient than malloc. Additionally to a usual obstack 0028 * like allocator you can also free the objects individually. Because it 0029 * does no compaction it still is faster than malloc()/free(). Depending 0030 * on the exact usage pattern that might come at the expense of some 0031 * memory though. 0032 * @author Waldo Bastian <bastian@kde.org>, Michael Matz <matz@kde.org> 0033 */ 0034 class KZoneAllocator 0035 { 0036 public: 0037 /** 0038 * Creates a KZoneAllocator object. 0039 * @param _blockSize Size in bytes of the blocks requested from malloc. 0040 */ 0041 explicit KZoneAllocator(unsigned long _blockSize = 8 * 1024); 0042 0043 /** 0044 * Destructs the ZoneAllocator and free all memory allocated by it. 0045 */ 0046 ~KZoneAllocator(); 0047 0048 KZoneAllocator(const KZoneAllocator &) = delete; 0049 KZoneAllocator &operator=(const KZoneAllocator &) = delete; 0050 0051 /** 0052 * Allocates a memory block. 0053 * @param _size Size in bytes of the memory block. Memory is aligned to 0054 * the size of a pointer. 0055 */ 0056 void *allocate(size_t _size); 0057 0058 /** 0059 * Gives back a block returned by allocate() to the zone 0060 * allocator, and possibly deallocates the block holding it (when it's 0061 * empty). The first deallocate() after many allocate() calls 0062 * (or the first at all) builds an internal data structure for speeding 0063 * up deallocation. The consistency of that structure is maintained 0064 * from then on (by allocate() and deallocate()) unless many 0065 * more objects are allocated without any intervening deallocation, in 0066 * which case it's thrown away and rebuilt at the next deallocate(). 0067 * 0068 * The effect of this is, that such initial deallocate() calls take 0069 * more time then the normal calls, and that after this list is built, i.e. 0070 * generally if deallocate() is used at all, also allocate() is a 0071 * little bit slower. This means, that if you want to squeeze out the last 0072 * bit performance you would want to use KZoneAllocator as an obstack, i.e. 0073 * just use the functions allocate() and free_since(). All the 0074 * remaining memory is returned to the system if the zone allocator 0075 * is destroyed. 0076 * @param ptr Pointer as returned by allocate(). 0077 */ 0078 void deallocate(void *ptr); 0079 0080 /** 0081 * Deallocate many objects at once. 0082 * free_since() deallocates all objects allocated after @p ptr, 0083 * @em including @p ptr itself. 0084 * 0085 * The intended use is something along the lines of: 0086 * \code 0087 * KZoneAllocator alloc(8192); 0088 * void *remember_me = alloc.allocate(0); 0089 * for (int i = 0; i < 1000; i++) 0090 * do_something_with (alloc.allocate(12)); 0091 * alloc.free_since (remember_me); 0092 * \endcode 0093 * Note, that we don't need to remember all the pointers to the 12-byte 0094 * objects for freeing them. The free_since() does deallocate them 0095 * all at once. 0096 * @param ptr Pointer as returned by allocate(). It acts like 0097 * a kind of mark of a certain position in the stack of all objects, 0098 * off which you can throw away everything above that mark. 0099 */ 0100 void free_since(void *ptr); 0101 0102 protected: 0103 /** A single chunk of memory from the heap. @internal */ 0104 class MemBlock; 0105 /**< A list of chunks. @internal */ 0106 typedef QList<MemBlock *> MemList; 0107 void addBlock(MemBlock *b); 0108 void delBlock(MemBlock *b); 0109 void insertHash(MemBlock *b); 0110 void initHash(); 0111 0112 private: 0113 class Private; 0114 Private *const d; 0115 }; 0116 0117 #endif