diff -r 516af714ebb4 -r f2950aff7424 perfsrv/memspy/Driver/Shared/heaputils.cpp --- a/perfsrv/memspy/Driver/Shared/heaputils.cpp Fri Sep 17 08:38:31 2010 +0300 +++ b/perfsrv/memspy/Driver/Shared/heaputils.cpp Mon Oct 04 02:45:59 2010 +0300 @@ -23,7 +23,7 @@ #include #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.