perfsrv/memspy/Driver/Shared/heaputils.cpp
changeset 55 f2950aff7424
parent 48 516af714ebb4
child 62 1c2bb2fc7c87
equal deleted inserted replaced
48:516af714ebb4 55:f2950aff7424
    21 
    21 
    22 #ifdef __KERNEL_MODE__
    22 #ifdef __KERNEL_MODE__
    23 
    23 
    24 #include <kern_priv.h>
    24 #include <kern_priv.h>
    25 #define MEM Kern
    25 #define MEM Kern
    26 __ASSERT_COMPILE(sizeof(LtkUtils::RKernelSideAllocatorHelper) == 10*4);
    26 __ASSERT_COMPILE(sizeof(LtkUtils::RUserAllocatorHelper) == 10*4);
    27 #define KERN_ENTER_CS() NKern::ThreadEnterCS()
    27 #define KERN_ENTER_CS() NKern::ThreadEnterCS()
    28 #define KERN_LEAVE_CS() NKern::ThreadLeaveCS()
    28 #define KERN_LEAVE_CS() NKern::ThreadLeaveCS()
    29 #define LOG(args...)
    29 #define LOG(args...)
    30 #define HUEXPORT_C
    30 #define HUEXPORT_C
    31 #else
    31 #else
   102 
   102 
   103 const TInt KTempBitmapSize = 256; // KMaxSlabPayload / mincellsize, technically. Close enough.
   103 const TInt KTempBitmapSize = 256; // KMaxSlabPayload / mincellsize, technically. Close enough.
   104 
   104 
   105 #ifdef __KERNEL_MODE__
   105 #ifdef __KERNEL_MODE__
   106 
   106 
       
   107 TLinAddr LtkUtils::RAllocatorHelper::GetKernelAllocator(DChunk* aKernelChunk) 
       
   108     {    
       
   109     TLinAddr allocatorAddress;
       
   110 #ifdef __WINS__
       
   111     allocatorAddress = (TLinAddr)aKernelChunk->Base();
       
   112 #else
       
   113     // Copied from P::KernelInfo
       
   114     const TRomHeader& romHdr=Epoc::RomHeader();
       
   115     const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry;
       
   116     const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin;
       
   117     TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize);
       
   118     TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize);
       
   119     allocatorAddress = heap;
       
   120 #endif
       
   121     return allocatorAddress;
       
   122     }
       
   123 
   107 TInt RAllocatorHelper::OpenKernelHeap()
   124 TInt RAllocatorHelper::OpenKernelHeap()
   108 	{
   125 	{
   109 	_LIT(KName, "SvHeap");
   126 	_LIT(KName, "SvHeap");
   110 	NKern::ThreadEnterCS();
   127 	NKern::ThreadEnterCS();
   111 	DObjectCon* chunkContainer = Kern::Containers()[EChunk];
   128 	DObjectCon* chunkContainer = Kern::Containers()[EChunk];
   122 			break;
   139 			break;
   123 			}
   140 			}
   124 		}
   141 		}
   125 	iChunk = foundChunk;
   142 	iChunk = foundChunk;
   126     chunkContainer->Signal();
   143     chunkContainer->Signal();
   127 #ifdef __WINS__
   144 
   128 	TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0); // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
   145     iAllocatorAddress = GetKernelAllocator(foundChunk);
   129 #else
   146 
   130 	// Copied from P::KernelInfo
   147     // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
   131 	const TRomHeader& romHdr=Epoc::RomHeader();
   148 	// 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.
   132 	const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry;
   149 	TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0); 
   133 	const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin;
   150 
   134 	TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize);
       
   135 	TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize);
       
   136 	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.
       
   137 
       
   138 #endif
       
   139 	if (!err) err = FinishConstruction();
   151 	if (!err) err = FinishConstruction();
   140 	NKern::ThreadLeaveCS();
   152 	NKern::ThreadLeaveCS();
   141 	return err;
   153 	return err;
   142 	}
   154 	}
   143 
   155 
   286 	return KErrNone;
   298 	return KErrNone;
   287 	}
   299 	}
   288 
   300 
   289 #ifdef __KERNEL_MODE__
   301 #ifdef __KERNEL_MODE__
   290 
   302 
   291 LtkUtils::RKernelSideAllocatorHelper::RKernelSideAllocatorHelper()
   303 LtkUtils::RUserAllocatorHelper::RUserAllocatorHelper()
   292 	: iThread(NULL)
   304 	: iThread(NULL)
   293 	{}
   305 	{}
   294 
   306 
   295 void LtkUtils::RKernelSideAllocatorHelper::Close()
   307 void LtkUtils::RUserAllocatorHelper::Close()
   296 	{
   308 	{
   297 	NKern::ThreadEnterCS();
   309 	NKern::ThreadEnterCS();
   298 	if (iThread)
   310 	if (iThread)
   299 		{
   311 		{
   300 		iThread->Close(NULL);
   312 		iThread->Close(NULL);
   302 	iThread = NULL;
   314 	iThread = NULL;
   303 	RAllocatorHelper::Close();
   315 	RAllocatorHelper::Close();
   304 	NKern::ThreadLeaveCS();
   316 	NKern::ThreadLeaveCS();
   305 	}
   317 	}
   306 
   318 
   307 TInt LtkUtils::RKernelSideAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
   319 TInt LtkUtils::RUserAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
   308 	{
   320 	{
   309 	return Kern::ThreadRawRead(iThread, (const TAny*)aLocation, aResult, aSize);
   321 	return Kern::ThreadRawRead(iThread, (const TAny*)aLocation, aResult, aSize);
   310 	}
   322 	}
   311 
   323 
   312 TInt LtkUtils::RKernelSideAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
   324 TInt LtkUtils::RUserAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
   313 	{
   325 	{
   314 	return Kern::ThreadRawWrite(iThread, (TAny*)aLocation, aData, aSize);
   326 	return Kern::ThreadRawWrite(iThread, (TAny*)aLocation, aData, aSize);
   315 	}
   327 	}
   316 
   328 
   317 TInt LtkUtils::RKernelSideAllocatorHelper::TryLock()
   329 TInt LtkUtils::RUserAllocatorHelper::TryLock()
   318 	{
   330 	{
   319 	return KErrNotSupported;
   331 	return KErrNotSupported;
   320 	}
   332 	}
   321 
   333 
   322 void LtkUtils::RKernelSideAllocatorHelper::TryUnlock()
   334 void LtkUtils::RUserAllocatorHelper::TryUnlock()
   323 	{
   335 	{
   324 	// Not supported
   336 	// Not supported
   325 	}
   337 	}
   326 
   338 
   327 TInt LtkUtils::RKernelSideAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb)
   339 TInt LtkUtils::RUserAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb)
   328 	{
   340 	{
   329 	NKern::ThreadEnterCS();
   341 	NKern::ThreadEnterCS();
   330 	DObjectCon* threads = Kern::Containers()[EThread];
   342 	DObjectCon* threads = Kern::Containers()[EThread];
   331 	threads->Wait();
   343 	threads->Wait();
   332 	iThread = Kern::ThreadFromId(aThreadId);
   344 	iThread = Kern::ThreadFromId(aThreadId);
   342 	TInt err = IdentifyAllocatorType(aEuserIsUdeb);
   354 	TInt err = IdentifyAllocatorType(aEuserIsUdeb);
   343 	if (err) Close();
   355 	if (err) Close();
   344 	return err;
   356 	return err;
   345 	}
   357 	}
   346 
   358 
       
   359 LtkUtils::RKernelCopyAllocatorHelper::RKernelCopyAllocatorHelper()
       
   360     : iCopiedChunk(NULL), iOffset(0)
       
   361     {}
       
   362 
       
   363 TInt LtkUtils::RKernelCopyAllocatorHelper::OpenCopiedHeap(DChunk* aOriginalChunk, DChunk* aCopiedChunk, TInt aOffset)
       
   364     {
       
   365     TInt err = aCopiedChunk->Open();
       
   366     if (!err)
       
   367         {
       
   368         iCopiedChunk = aCopiedChunk;
       
   369         iOffset = aOffset;
       
   370 
       
   371         // We need to set iAllocatorAddress to point to the allocator in the original chunk and not the copy
       
   372         // because all the internal pointers will be relative to that. Instead we use iOffset in the Read / Write Data 
       
   373         // calls
       
   374         iAllocatorAddress = GetKernelAllocator(aOriginalChunk);
       
   375         
       
   376         // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
       
   377         // 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.
       
   378         err = OpenChunkHeap((TLinAddr)aCopiedChunk->Base(), 0);
       
   379         }
       
   380     
       
   381     return err;
       
   382     }
       
   383 
       
   384 DChunk* LtkUtils::RKernelCopyAllocatorHelper::OpenUnderlyingChunk()
       
   385     {
       
   386     // We should never get here
       
   387     __NK_ASSERT_ALWAYS(EFalse);
       
   388     return NULL;
       
   389     }
       
   390 
       
   391 void LtkUtils::RKernelCopyAllocatorHelper::Close()
       
   392     {
       
   393     if (iCopiedChunk)
       
   394         {
       
   395         NKern::ThreadEnterCS();
       
   396         iCopiedChunk->Close(NULL);
       
   397         iCopiedChunk = NULL;
       
   398         NKern::ThreadLeaveCS();
       
   399         }
       
   400     iOffset = 0;
       
   401     RAllocatorHelper::Close();
       
   402     }
       
   403 
       
   404 TInt LtkUtils::RKernelCopyAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
       
   405     {
       
   406     memcpy(aResult, (const TAny*)(aLocation+iOffset), aSize);
       
   407     return KErrNone;
       
   408     }
       
   409 
       
   410 TInt LtkUtils::RKernelCopyAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
       
   411     {
       
   412     memcpy((TAny*)(aLocation+iOffset), aData, aSize);
       
   413     return KErrNone;
       
   414     }
       
   415 
       
   416 TInt LtkUtils::RKernelCopyAllocatorHelper::TryLock()
       
   417     {
       
   418     return KErrNotSupported;
       
   419     }
       
   420 
       
   421 void LtkUtils::RKernelCopyAllocatorHelper::TryUnlock()
       
   422     {
       
   423     // Not supported
       
   424     }
       
   425 
   347 #endif // __KERNEL_MODE__
   426 #endif // __KERNEL_MODE__
   348 
   427 
   349 TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
   428 TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
   350 	{
   429 	{
   351 	iAllocatorAddress = aChunkBase;
       
   352 #ifdef __KERNEL_MODE__
   430 #ifdef __KERNEL_MODE__
   353 	// Must be in CS
   431 	// Must be in CS
   354 	// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap.
   432 	// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap.
   355 	TInt udeb = EFalse; // We can't figure this out until after we've got the heap
   433 	TInt udeb = EFalse; // We can't figure this out until after we've got the heap
   356 	TBool isTheKernelHeap = ETrue;
   434 	TBool isTheKernelHeap = ETrue;
  1600 	TInt err = iChunk->Open();
  1678 	TInt err = iChunk->Open();
  1601 	if (err) return NULL;
  1679 	if (err) return NULL;
  1602 	return iChunk;
  1680 	return iChunk;
  1603 	}
  1681 	}
  1604 
  1682 
  1605 DChunk* LtkUtils::RKernelSideAllocatorHelper::OpenUnderlyingChunk()
  1683 DChunk* LtkUtils::RUserAllocatorHelper::OpenUnderlyingChunk()
  1606 	{
  1684 	{
  1607 	if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
  1685 	if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
  1608 	// Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
  1686 	// Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
  1609 	// It is for this reason that iChunk is private, to remove temptation
  1687 	// It is for this reason that iChunk is private, to remove temptation
  1610 	
  1688