diff -r 000000000000 -r 96e5fb8b040d kernel/eka/common/alloc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/common/alloc.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,524 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\common\alloc.cpp +// +// + +#include "common.h" +#include + + + +#ifndef __KERNEL_MODE__ +/** +Opens this heap for shared access. + +Opening the heap increases the heap's access count by one. + +@return KErrNone if successful; + KErrGeneral, if the original valeu of the access count + was not positive. +*/ +EXPORT_C TInt RAllocator::Open() + { + TInt c = __e32_atomic_tas_ord32(&iAccessCount, 1, 1, 0); + return (c>0) ? KErrNone : KErrGeneral; + } + + + + +/** +Closes this shared heap. + +Closing the heap decreases the heap's access count by one. + +@panic USER 57 if the access count has already reached zero. +*/ +EXPORT_C void RAllocator::Close() + { + TInt count = __e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0); + __ASSERT_ALWAYS(count>0, Panic(EAllocatorClosedTooManyTimes)); + if (count==1) + DoClose(); + } + + + +/** +@internalComponent +*/ +EXPORT_C void RAllocator::DoClose() + { + __ASSERT_ALWAYS(TUint32(iHandleCount)<=TUint32(EMaxHandles), Panic(EAllocatorBadHandleCount)); + TInt handle[EMaxHandles]; + TInt c = iHandleCount; + wordmove(handle, iHandles, c*sizeof(TInt)); + memclr(iHandles, c*sizeof(TInt)); + TInt* pH = handle; + TInt* pE = pH + c; + while (pHDebugFunction(ECount, &aFreeCount); + } +#endif + + + + +/** +Checks the validity of the heap. + +The function walks through the list of allocated cells and the list of +free cells checking that this heap is consistent and complete. + +@panic USER 47 if any corruption is found, specifically a bad allocated + heap cell size. +@panic USER 48 if any corruption is found, specifically a bad allocated + heap cell address. +@panic USER 49 if any corruption is found, specifically a bad free heap + cell address. +*/ +UEXPORT_C void RAllocator::Check() const + { + ((RAllocator*)this)->DebugFunction(ECheck); + } + + + + +/** +Marks the start of heap cell checking for this heap. + +If earlier calls to __DbgMarkStart() have been made, then this call +to __DbgMarkStart() marks the start of a new nested level of +heap cell checking. + +Every call to __DbgMarkStart() should be matched by a later call +to __DbgMarkEnd() to verify that the number of heap cells allocated, +at the current nested level, is as expected. This expected number of heap cells +is passed to __DbgMarkEnd() as a parameter; however, the most common expected +number is zero, reflecting the fact that most developers check that all memory +allocated since a previous call to __DbgMarkStart() has been freed. + +@see RAllocator::__DbgMarkEnd() +*/ +UEXPORT_C void RAllocator::__DbgMarkStart() + { + DebugFunction(EMarkStart); + } + + + + +/** +Marks the end of heap cell checking at the current nested level for this heap. + +A call to this function should match an earlier call to __DbgMarkStart(). +If there are more calls to this function than calls to __DbgMarkStart(), +then this function raises a USER 51 panic. + +The function checks that the number of heap cells allocated, at the current +nested level, is aCount. The most common value for aCount is zero, reflecting +the fact that most developers check that all memory allocated since a previous +call to __DbgMarkStart() has been freed. + +If the check fails, the function returns a pointer to the first orphaned +heap cell. + +@param aCount The number of allocated heap cells expected. + +@return A pointer to the first orphaned heap cell, if verification fails; + zero otherwise. + +@see RAllocator::__DbgMarkStart() +*/ +UEXPORT_C TUint32 RAllocator::__DbgMarkEnd(TInt aCount) + { + return DebugFunction(EMarkEnd, (TAny*)aCount); + } + + + + +/** +Checks the current number of allocated heap cells for this heap. + +If aCountAll is true, the function checks that the total number of allocated +cells on this heap is the same as aCount. If aCountAll is false, then +the function checks that the number of allocated cells at the current nested +level is the same as aCount. + +If checking fails, the function raises a panic; +information about the failure is put into the panic category; +this takes the form: + +ALLOC COUNT\\rExpected aaa\\rAllocated bbb\\rLn: ccc ddddd + +where + +1. aaaa is the value aCount + +2. bbbb is the number of allocated heap cells + +3. ccc is a line number, copied from aLineNum + +4. ddddd is a file name, copied from the descriptor aFileName + +Note that the panic number is 1. + +@param aCountAll If true, the function checks that the total number of + allocated cells on this heap is the same as aCount. + If false, the function checks that the number of allocated + cells at the current nested level is the same as aCount. +@param aCount The expected number of allocated cells. +@param aFileName A filename; this is displayed as part of the panic + category if the check fails. +@param aLineNum A line number; this is displayed as part of the panic category + if the check fails. + +@return KErrNone, if successful; otherwise one of the other system wide error codes. +*/ +UEXPORT_C TInt RAllocator::__DbgMarkCheck(TBool aCountAll, TInt aCount, const TDesC8& aFileName, TInt aLineNum) + { + SCheckInfo info; + info.iAll = aCountAll; + info.iCount = aCount; + info.iFileName = &aFileName; + info.iLineNum = aLineNum; + return DebugFunction(ECheck, &info); + } + + + + +/** +Simulates a heap allocation failure for this heap. + +The failure occurs on subsequent calls to new or any of the functions which +allocate memory from this heap. + +The timing of the allocation failure depends on the type of +allocation failure requested, i.e. on the value of aType. + +The simulation of heap allocation failure is cancelled +if aType is given the value RAllocator::ENone. + +Notes: + +1. If the failure type is RAllocator::EFailNext, the next attempt to allocate from + this heap fails; however, no further failures will occur. + +2. For failure types RAllocator::EFailNext and RAllocator::ENone, set aRate to 1. + +@param aType An enumeration which indicates how to simulate heap + allocation failure. +@param aRate The rate of failure; when aType is RAllocator::EDeterministic, + heap allocation fails every aRate attempts +*/ +UEXPORT_C void RAllocator::__DbgSetAllocFail(TAllocFail aType, TInt aRate) + { + DebugFunction(ESetFail, (TAny*)aType, (TAny*)aRate); + } + + +/** +Simulates a burst of heap allocation failures for this heap. + +The failure occurs for aBurst allocations attempt via subsequent calls +to new or any of the functions which allocate memory from this heap. + +The timing of the allocation failure depends on the type of +allocation failure requested, i.e. on the value of aType. + +The simulation of heap allocation failure is cancelled +if aType is given the value RAllocator::ENone. + +Notes: + +1. If the failure type is RAllocator::EFailNext or RAllocator::EBurstFailNext, +the next one or aBurst attempts to allocate from this heap will fail; +however, no further failures will occur. + +2. For failure types RAllocator::EFailNext and RAllocator::ENone, set aRate to 1. + +@param aType An enumeration which indicates how to simulate heap + allocation failure. +@param aRate The rate of failure; when aType is RAllocator::EDeterministic, + heap allocation fails every aRate attempts. +@param aBurst The number of consecutive heap allocations that will fail each +time the allocations should fail. + +@see RAllocator::TAllocFail +*/ +UEXPORT_C void RAllocator::__DbgSetBurstAllocFail(TAllocFail aType, TUint aRate, TUint aBurst) + { + SRAllocatorBurstFail burstFail; + burstFail.iRate = aRate; + burstFail.iBurst = aBurst; + DebugFunction(ESetBurstFail, (TAny*)aType, (TAny*)&burstFail); + } + +/** +Returns the number of heap allocation failures the current debug allocator fail +function has caused so far. + +This is intended to only be used with fail types RAllocator::EFailNext, +RAllocator::EBurstFailNext, RAllocator::EDeterministic and +RAllocator::EBurstDeterministic. The return value is unreliable for +all other fail types. + +@return The number of heap allocation failures the current debug fail +function has caused. + +@see RAllocator::TAllocFail +*/ +UEXPORT_C TUint RAllocator::__DbgCheckFailure() + { + return DebugFunction(ECheckFailure); + } + + +UEXPORT_C TInt RAllocator::Extension_(TUint, TAny*& a0, TAny*) + { + a0 = NULL; + return KErrExtensionNotSupported; + }