diff -r 000000000000 -r a41df078684a kernel/eka/memmodel/epoc/moving/mkernel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/memmodel/epoc/moving/mkernel.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,137 @@ +// 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\memmodel\epoc\moving\mkernel.cpp +// +// + +#include "memmodel.h" + +/******************************************** + * Thread + ********************************************/ + +TInt DThread::AllocateSupervisorStack() + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateSupervisorStack %O %x",this,iSupervisorStackSize)); + iSupervisorStackSize=Mmu::RoundToPageSize(iSupervisorStackSize); + if (iThreadType!=EThreadInitial) + { + TInt offset=MM::SvStackChunk->Allocate(iSupervisorStackSize,PP::SupervisorThreadStackGuard); + if (offset<0) + { + __KTRACE_FAIL(KErrNoMemory,Kern::Printf("ASS: %d",KErrNoMemory)); + return KErrNoMemory; + } + iSupervisorStack=MM::SvStackChunk->Base()+offset+PP::SupervisorThreadStackGuard; + iSupervisorStackAllocated = TRUE; + __KTRACE_OPT(KTHREAD,Kern::Printf("Supervisor stack at %x, size %x",iSupervisorStack,iSupervisorStackSize)); + } + return KErrNone; + } + +void DThread::FreeSupervisorStack() + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this)); + if (iSupervisorStackAllocated) + { + TAny* pStack = __e32_atomic_swp_ord_ptr(&iSupervisorStack, 0); + if (pStack && iThreadType!=EThreadInitial) + { + __KTRACE_OPT(KTHREAD,Kern::Printf("Freeing supervisor stack at %08x, size %x",pStack,iSupervisorStackSize)); + TInt offset=(TUint8*)pStack-MM::SvStackChunk->Base(); + MM::SvStackChunk->Decommit(offset-PP::SupervisorThreadStackGuard,iSupervisorStackSize+PP::SupervisorThreadStackGuard); + } + } + iSupervisorStackAllocated = FALSE; + } + +TInt DThread::AllocateUserStack(TInt aSize, TBool /*aPaged*/) + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize)); + + aSize=Mmu::RoundToPageSize(aSize); + if (aSize>PP::MaxUserThreadStack) + return KErrTooBig; + TInt guard=PP::UserThreadStackGuard; + DProcess* pP=iOwningProcess; + NKern::LockSystem(); + DChunk* pC=pP->iDataBssStackChunk; + if (!pC || pC->Open()!=KErrNone) // so chunk doesn't disappear during Allocate() + { + NKern::UnlockSystem(); + __KTRACE_FAIL(KErrDied,Kern::Printf("AUS1: %d",KErrDied)); + return KErrDied; + } + NKern::UnlockSystem(); + TInt r=pC->Allocate(aSize,guard); + TInt s=pC->Close(NULL); // NULL since we didn't add chunk to process again + if (s & EObjectDeleted) + { + __KTRACE_FAIL(KErrDied,Kern::Printf("AUS2: %d",KErrDied)); + return KErrDied; + } + if (r<0) + { + __KTRACE_FAIL(r,Kern::Printf("AUS3: %d",r)); + return r; + } + iUserStackSize=aSize; + iUserStackRunAddress=pP->iDataBssRunAddress+r+guard; + __KTRACE_OPT(KTHREAD,Kern::Printf("User stack run address at %x",iUserStackRunAddress)); + return KErrNone; + } + +void DThread::FreeUserStack() + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this)); + TLinAddr usr_stack = (TLinAddr)__e32_atomic_swp_ord_ptr(&iUserStackRunAddress, 0); + if (usr_stack) + { + __KTRACE_OPT(KTHREAD,Kern::Printf("Freeing user stack at %x",usr_stack)); + DMemModelProcess* pP=(DMemModelProcess*)iOwningProcess; + NKern::LockSystem(); + DMemModelChunk* pC=(DMemModelChunk*)pP->iDataBssStackChunk; + if (!pC || pC->Open()!=KErrNone) // so chunk doesn't disappear during Decommit() + { + NKern::UnlockSystem(); + __KTRACE_FAIL(KErrDied,Kern::Printf("FUS")); + return; + } + NKern::UnlockSystem(); + TInt offset=usr_stack-pP->iDataBssRunAddress; + pC->Decommit(offset-PP::UserThreadStackGuard,iUserStackSize+PP::UserThreadStackGuard); + pC->Close(NULL); // NULL since we didn't add chunk to process again + } + } + +void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext) + { + aThread->iIpcClient = 0; + TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap; + switch (xt.ExcLocation(aThread, aContext)) + { + case TIpcExcTrap::EExcRemote: + // problem accessing remote address - 'leave' so an error code will be returned + xt.Exception(KErrBadDescriptor); // does not return + + case TIpcExcTrap::EExcLocal: + // problem accessing local address - return and panic current thread as usual + NKern::UnlockSystem(); + return; + + default: + // otherwise return and fault kernel + return; + } + }