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 |
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 |