--- a/perfsrv/memspy/Driver/Shared/heaputils.cpp Mon Sep 06 15:00:47 2010 +0300
+++ b/perfsrv/memspy/Driver/Shared/heaputils.cpp Mon Sep 20 12:20:18 2010 +0300
@@ -23,7 +23,7 @@
#include <kern_priv.h>
#define MEM Kern
-__ASSERT_COMPILE(sizeof(LtkUtils::RKernelSideAllocatorHelper) == 10*4);
+__ASSERT_COMPILE(sizeof(LtkUtils::RUserAllocatorHelper) == 10*4);
#define KERN_ENTER_CS() NKern::ThreadEnterCS()
#define KERN_LEAVE_CS() NKern::ThreadLeaveCS()
#define LOG(args...)
@@ -104,6 +104,23 @@
#ifdef __KERNEL_MODE__
+TLinAddr LtkUtils::RAllocatorHelper::GetKernelAllocator(DChunk* aKernelChunk)
+ {
+ TLinAddr allocatorAddress;
+#ifdef __WINS__
+ allocatorAddress = (TLinAddr)aKernelChunk->Base();
+#else
+ // Copied from P::KernelInfo
+ const TRomHeader& romHdr=Epoc::RomHeader();
+ const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry;
+ const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin;
+ TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize);
+ TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize);
+ allocatorAddress = heap;
+#endif
+ return allocatorAddress;
+ }
+
TInt RAllocatorHelper::OpenKernelHeap()
{
_LIT(KName, "SvHeap");
@@ -124,18 +141,13 @@
}
iChunk = foundChunk;
chunkContainer->Signal();
-#ifdef __WINS__
- TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0); // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
-#else
- // Copied from P::KernelInfo
- const TRomHeader& romHdr=Epoc::RomHeader();
- const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry;
- const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin;
- TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize);
- TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize);
- TInt err = OpenChunkHeap(heap, 0); // aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero.
+
+ iAllocatorAddress = GetKernelAllocator(foundChunk);
-#endif
+ // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
+ // aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero.
+ TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0);
+
if (!err) err = FinishConstruction();
NKern::ThreadLeaveCS();
return err;
@@ -288,11 +300,11 @@
#ifdef __KERNEL_MODE__
-LtkUtils::RKernelSideAllocatorHelper::RKernelSideAllocatorHelper()
+LtkUtils::RUserAllocatorHelper::RUserAllocatorHelper()
: iThread(NULL)
{}
-void LtkUtils::RKernelSideAllocatorHelper::Close()
+void LtkUtils::RUserAllocatorHelper::Close()
{
NKern::ThreadEnterCS();
if (iThread)
@@ -304,27 +316,27 @@
NKern::ThreadLeaveCS();
}
-TInt LtkUtils::RKernelSideAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
+TInt LtkUtils::RUserAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
{
return Kern::ThreadRawRead(iThread, (const TAny*)aLocation, aResult, aSize);
}
-TInt LtkUtils::RKernelSideAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
+TInt LtkUtils::RUserAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
{
return Kern::ThreadRawWrite(iThread, (TAny*)aLocation, aData, aSize);
}
-TInt LtkUtils::RKernelSideAllocatorHelper::TryLock()
+TInt LtkUtils::RUserAllocatorHelper::TryLock()
{
return KErrNotSupported;
}
-void LtkUtils::RKernelSideAllocatorHelper::TryUnlock()
+void LtkUtils::RUserAllocatorHelper::TryUnlock()
{
// Not supported
}
-TInt LtkUtils::RKernelSideAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb)
+TInt LtkUtils::RUserAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb)
{
NKern::ThreadEnterCS();
DObjectCon* threads = Kern::Containers()[EThread];
@@ -344,11 +356,77 @@
return err;
}
+LtkUtils::RKernelCopyAllocatorHelper::RKernelCopyAllocatorHelper()
+ : iCopiedChunk(NULL), iOffset(0)
+ {}
+
+TInt LtkUtils::RKernelCopyAllocatorHelper::OpenCopiedHeap(DChunk* aOriginalChunk, DChunk* aCopiedChunk, TInt aOffset)
+ {
+ TInt err = aCopiedChunk->Open();
+ if (!err)
+ {
+ iCopiedChunk = aCopiedChunk;
+ iOffset = aOffset;
+
+ // We need to set iAllocatorAddress to point to the allocator in the original chunk and not the copy
+ // because all the internal pointers will be relative to that. Instead we use iOffset in the Read / Write Data
+ // calls
+ iAllocatorAddress = GetKernelAllocator(aOriginalChunk);
+
+ // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
+ // aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero.
+ err = OpenChunkHeap((TLinAddr)aCopiedChunk->Base(), 0);
+ }
+
+ return err;
+ }
+
+DChunk* LtkUtils::RKernelCopyAllocatorHelper::OpenUnderlyingChunk()
+ {
+ // We should never get here
+ __NK_ASSERT_ALWAYS(EFalse);
+ return NULL;
+ }
+
+void LtkUtils::RKernelCopyAllocatorHelper::Close()
+ {
+ if (iCopiedChunk)
+ {
+ NKern::ThreadEnterCS();
+ iCopiedChunk->Close(NULL);
+ iCopiedChunk = NULL;
+ NKern::ThreadLeaveCS();
+ }
+ iOffset = 0;
+ RAllocatorHelper::Close();
+ }
+
+TInt LtkUtils::RKernelCopyAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
+ {
+ memcpy(aResult, (const TAny*)(aLocation+iOffset), aSize);
+ return KErrNone;
+ }
+
+TInt LtkUtils::RKernelCopyAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
+ {
+ memcpy((TAny*)(aLocation+iOffset), aData, aSize);
+ return KErrNone;
+ }
+
+TInt LtkUtils::RKernelCopyAllocatorHelper::TryLock()
+ {
+ return KErrNotSupported;
+ }
+
+void LtkUtils::RKernelCopyAllocatorHelper::TryUnlock()
+ {
+ // Not supported
+ }
+
#endif // __KERNEL_MODE__
TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
{
- iAllocatorAddress = aChunkBase;
#ifdef __KERNEL_MODE__
// Must be in CS
// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap.
@@ -1602,7 +1680,7 @@
return iChunk;
}
-DChunk* LtkUtils::RKernelSideAllocatorHelper::OpenUnderlyingChunk()
+DChunk* LtkUtils::RUserAllocatorHelper::OpenUnderlyingChunk()
{
if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
// Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.