os/kernelhwsrv/kernel/eka/memmodel/epoc/flexible/mmu/mslaballoc.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
/**
sl@0
    17
 @file
sl@0
    18
 @internalComponent
sl@0
    19
*/
sl@0
    20
sl@0
    21
#ifndef MSLABALLOC_H
sl@0
    22
#define MSLABALLOC_H
sl@0
    23
sl@0
    24
#include "mcleanup.h"
sl@0
    25
sl@0
    26
/**
sl@0
    27
Slab allocator.
sl@0
    28
*/
sl@0
    29
class RSlabAllocatorBase
sl@0
    30
	{
sl@0
    31
public:
sl@0
    32
	RSlabAllocatorBase(TBool aDelayedCleanup);
sl@0
    33
	~RSlabAllocatorBase();
sl@0
    34
sl@0
    35
	/**
sl@0
    36
	Construct a slab allocator.
sl@0
    37
sl@0
    38
	@param aMaxSlabs	Maximum number of slabs to use. (Number of bits in \a slabBits.)
sl@0
    39
	@param aObjectSize	Size of objects to allocate.
sl@0
    40
	*/
sl@0
    41
	TInt Construct(TUint aMaxSlabs, TUint aObjectSize);
sl@0
    42
sl@0
    43
	/**
sl@0
    44
	Construct a slab allocator using fixed virtual memory.
sl@0
    45
sl@0
    46
	@param aMaxSlabs	Maximum number of slabs to use. (Number of bits in \a slabBits.)
sl@0
    47
	@param aObjectSize	Size of objects to allocate.
sl@0
    48
	@param aBase		Virtual address for start of memory where slabs will be allocated.
sl@0
    49
						Zero indicates 'anywhere'.
sl@0
    50
	*/
sl@0
    51
	TInt Construct(TUint aMaxSlabs, TUint aObjectSize, TLinAddr aBase);
sl@0
    52
sl@0
    53
	/**
sl@0
    54
	Set the memory object to be used for the slab allocator.
sl@0
    55
	*/
sl@0
    56
	FORCE_INLINE void SetMemory(DMemoryObject* aMemory, TUint aReserveCount)
sl@0
    57
		{
sl@0
    58
		__NK_ASSERT_DEBUG(!iMemory);
sl@0
    59
		iMemory = aMemory;
sl@0
    60
		iReserveCount = aReserveCount;
sl@0
    61
		}
sl@0
    62
sl@0
    63
	/**
sl@0
    64
	Allocate an object.
sl@0
    65
sl@0
    66
	@return Allocated object, or the null pointer if there is insufficient memory to perform the allocation.
sl@0
    67
sl@0
    68
	@pre MmuLock held
sl@0
    69
	@post MmuLock held, but has always beet flashed
sl@0
    70
	*/
sl@0
    71
	TAny* Alloc();
sl@0
    72
sl@0
    73
	/**
sl@0
    74
	Free an object previously allocated with #Alloc.
sl@0
    75
sl@0
    76
	@param aObject The object.
sl@0
    77
sl@0
    78
	@pre MmuLock held
sl@0
    79
	@post MmuLock held, but has always beet flashed
sl@0
    80
	*/
sl@0
    81
	void Free(TAny* aObject);
sl@0
    82
sl@0
    83
protected:
sl@0
    84
	class TSlabHeader : public SDblQueLink
sl@0
    85
		{
sl@0
    86
	public:
sl@0
    87
		SDblQue iFreeList;		///< List of unallocated objects in list.
sl@0
    88
		TUint iAllocCount;		///< Number of objects allocated in this slab.
sl@0
    89
		TAny* iHighWaterMark;	///< End of initialise region in slab.
sl@0
    90
		};
sl@0
    91
sl@0
    92
private:
sl@0
    93
	TBool NewSlab();
sl@0
    94
	void InitSlab(TLinAddr aPage);
sl@0
    95
	void FreeSlab(TSlabHeader* aSlab);
sl@0
    96
	static void CleanupTrampoline(TAny* aSelf);
sl@0
    97
	void Cleanup();
sl@0
    98
#ifdef _DEBUG
sl@0
    99
	void CheckSlab(TSlabHeader* aSlab);
sl@0
   100
#endif
sl@0
   101
sl@0
   102
private:
sl@0
   103
	SDblQue iFreeList;			///< List of slabs which have unallocated objects in them.
sl@0
   104
	TUint iFreeCount;			///< Number of unallocated objects.
sl@0
   105
	TUint iReserveCount;		///< Number of unallocated objects to keep in reserve (to allow for recursion during allocation).
sl@0
   106
	TUint iObjectsPerSlab;		///< Number of objects in each slab.
sl@0
   107
	TUint iObjectSize;			///< Size, in bytes, of objects to be allocated.
sl@0
   108
	TSpinLock iSpinLock;		///< Spinlock which protects iFreeList, iFreeCount  and TSlabHeader contents.
sl@0
   109
sl@0
   110
	TMemoryCleanup iCleanup;	///< Used to queue Cleanup() if iDelayedCleanup is true.
sl@0
   111
	TBool iDelayedCleanup;		///< True, if Free() should not free empty slabs.
sl@0
   112
sl@0
   113
	TBool iAllocatingSlab;		///< True if a new slab page is being allocated.
sl@0
   114
	TBitMapAllocator* iSlabMap;	///< Bitmap of allocated slabs.
sl@0
   115
	DMemoryObject* iMemory;		///< The memory object used to store slabs.
sl@0
   116
	DMemoryMapping* iMapping;	///< The memory mapping used for slabs.
sl@0
   117
	TLinAddr iBase;				///< Address of first slab.
sl@0
   118
	};
sl@0
   119
sl@0
   120
sl@0
   121
/**
sl@0
   122
Template for a slab allocator which can allocate up to N objects of type T.
sl@0
   123
*/
sl@0
   124
template <class T, TUint N>
sl@0
   125
class RSlabAllocator : public RSlabAllocatorBase
sl@0
   126
	{
sl@0
   127
public:
sl@0
   128
	enum
sl@0
   129
		{
sl@0
   130
		EObjectSize = sizeof(T)>sizeof(SDblQueLink) ? sizeof(T) : sizeof(SDblQueLink),
sl@0
   131
		EObjectsPerSlab = (KPageSize-sizeof(TSlabHeader))/EObjectSize,
sl@0
   132
		EMaxSlabs = (N+EObjectsPerSlab-1)/EObjectsPerSlab
sl@0
   133
		};
sl@0
   134
sl@0
   135
	FORCE_INLINE RSlabAllocator()
sl@0
   136
		: RSlabAllocatorBase(EFalse)
sl@0
   137
		{
sl@0
   138
		__ASSERT_COMPILE(EObjectsPerSlab>0);
sl@0
   139
		}
sl@0
   140
sl@0
   141
	FORCE_INLINE TInt Construct()
sl@0
   142
		{
sl@0
   143
		return RSlabAllocatorBase::Construct(EMaxSlabs,EObjectSize);
sl@0
   144
		}
sl@0
   145
sl@0
   146
	/**
sl@0
   147
	Allocate an object.
sl@0
   148
sl@0
   149
	@return Allocated object, or the null pointer if there is insufficient memory to perform the allocation.
sl@0
   150
	*/
sl@0
   151
	FORCE_INLINE T* Alloc()
sl@0
   152
		{
sl@0
   153
		return (T*)RSlabAllocatorBase::Alloc();
sl@0
   154
		}
sl@0
   155
sl@0
   156
	/**
sl@0
   157
	Free an object previously allocated with #Alloc.
sl@0
   158
sl@0
   159
	@param aObject Object.
sl@0
   160
	*/
sl@0
   161
	FORCE_INLINE void Free(T* aObject)
sl@0
   162
		{
sl@0
   163
		RSlabAllocatorBase::Free(aObject);
sl@0
   164
		}
sl@0
   165
	};
sl@0
   166
sl@0
   167
sl@0
   168
/**
sl@0
   169
Template for a slab allocator for allocating objects of type T, using the
sl@0
   170
virtual address region [B..E)
sl@0
   171
*/
sl@0
   172
template <class T, TLinAddr B, TLinAddr E>
sl@0
   173
class RStaticSlabAllocator : public RSlabAllocatorBase
sl@0
   174
	{
sl@0
   175
public:
sl@0
   176
	enum
sl@0
   177
		{
sl@0
   178
		EObjectSize = sizeof(T)>sizeof(SDblQueLink) ? sizeof(T) : sizeof(SDblQueLink),
sl@0
   179
		EObjectsPerSlab = (KPageSize-sizeof(TSlabHeader))/EObjectSize,
sl@0
   180
		EMaxSlabs = (E-B)/KPageSize
sl@0
   181
		};
sl@0
   182
sl@0
   183
	FORCE_INLINE RStaticSlabAllocator()
sl@0
   184
		: RSlabAllocatorBase(ETrue)
sl@0
   185
		{
sl@0
   186
		__ASSERT_COMPILE(EObjectsPerSlab>0);
sl@0
   187
		}
sl@0
   188
sl@0
   189
	FORCE_INLINE TInt Construct()
sl@0
   190
		{
sl@0
   191
		return RSlabAllocatorBase::Construct(EMaxSlabs,EObjectSize,B);
sl@0
   192
		}
sl@0
   193
sl@0
   194
	/**
sl@0
   195
	Allocate an object.
sl@0
   196
sl@0
   197
	@return Allocated object, or the null pointer if there is insufficient memory to perform the allocation.
sl@0
   198
	*/
sl@0
   199
	FORCE_INLINE T* Alloc()
sl@0
   200
		{
sl@0
   201
		return (T*)RSlabAllocatorBase::Alloc();
sl@0
   202
		}
sl@0
   203
sl@0
   204
	/**
sl@0
   205
	Free an object previously allocated with #Alloc.
sl@0
   206
sl@0
   207
	@param aObject Object.
sl@0
   208
	*/
sl@0
   209
	FORCE_INLINE void Free(T* aObject)
sl@0
   210
		{
sl@0
   211
		RSlabAllocatorBase::Free(aObject);
sl@0
   212
		}
sl@0
   213
	};
sl@0
   214
sl@0
   215
#endif
sl@0
   216