コード例 #1
0
ファイル: ac_memory.cpp プロジェクト: gaopan461/acoral
	void* SmallMemoryAlloc::allocate(size_t size)
	{
		size_t idx = ChunkIndex(size);
		ACCHECK(idx < CST_CHUNK_NUMBER);

		//锁指定大小的内存池
		ThreadGuard guard(&m_vtGuard[idx]);

		SMemoryList* &temp = m_vtFreeList[idx];
		if (!temp)
		{
			//内存池空,分配一个新的chunk做内存池
			SMemoryList* newChunk=AllocChunk(idx);
			SChunkList* chunkNode;

			//此处chunkNode也通过Memory分配器分配内存
			if(ChunkIndex(sizeof(SChunkList)) == idx)
			{
				chunkNode = reinterpret_cast<SChunkList *>(temp);
				temp = temp->m_pNext;
			}
			else
			{
				chunkNode = reinterpret_cast<SChunkList *>(allocate(sizeof(SChunkList)));
			}

			ThreadGuard guard(&m_nChunkGuard);

			//将新分配出来的chunk链接到chunk链表表头
			chunkNode->m_pNext = m_pChunkList;
			chunkNode->m_pData = newChunk;
			m_pChunkList = chunkNode;
		}

		//从内存池中取出一个内存
		void* ret = temp;
		temp = temp->m_pNext;
		return ret;
	}
コード例 #2
0
ファイル: ac_memory.cpp プロジェクト: gaopan461/acoral
	void SmallMemoryAlloc::deallocate(void* p, size_t size)
	{
		//得到该对象大小对应的内存池
		size_t idx = ChunkIndex(size);
		ACCHECK(idx < CST_CHUNK_NUMBER);

		SMemoryList* freeBlock = reinterpret_cast<SMemoryList *>(p);
		ThreadGuard guard(&m_vtGuard[idx]);

		//释放的对象的内存链接到内存池链表表头
		SMemoryList* &temp = m_vtFreeList[idx];
		freeBlock->m_pNext = temp;
		temp = freeBlock;
	}
コード例 #3
0
ファイル: mprocess.cpp プロジェクト: kuailexs/symbiandump-os1
TUint8* DMemModelProcess::DataSectionBase(DMemModelChunk* aChunk)
	{
	// this can't be called after $LOCK is deleted
	Kern::MutexWait(*iProcessLock);
	TInt pos=0;
	TInt r=ChunkIndex(aChunk,pos);
	if (r==0) // Found the chunk
		{
		TUint8* answer=((TUint8*)iChunks[pos].iDataSectionBase);
		__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::DataSectionBase %x",answer));
		Kern::MutexSignal(*iProcessLock);
		return answer;
		}
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::DataSectionBase chunk %08x not present in %08x",aChunk,this));
	Kern::MutexSignal(*iProcessLock);
	return(NULL);
	}
コード例 #4
0
ファイル: mprocess.cpp プロジェクト: kuailexs/symbiandump-os1
void DMemModelProcess::RemoveChunk(DMemModelChunk *aChunk)
	{
	// note that this can't be called after the process $LOCK mutex has been deleted
	// since it can only be called by a thread in this process doing a handle close or
	// dying, or by the process handles array being deleted due to the process dying,
	// all of which happen before $LOCK is deleted.
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess %O RemoveChunk %O",this,aChunk));
	Kern::MutexWait(*iProcessLock);
	TInt i = ChunkIndex(aChunk);
	if(i>=0) // Found the chunk
		{
		__KTRACE_OPT(KPROC,Kern::Printf("Chunk access count %d",iChunks[i].iAccessCount));
		if(--iChunks[i].iAccessCount==0)
			{
			DoRemoveChunk(i);
			}
		}
	Kern::MutexSignal(*iProcessLock);
	}
コード例 #5
0
ファイル: mprocess.cpp プロジェクト: kuailexs/symbiandump-os1
void DMemModelProcess::RemoveChunk(DMemModelChunk *aChunk)
	{
	// note that this can't be called after the process $LOCK mutex has been deleted
	// since it can only be called by a thread in this process doing a handle close or
	// dying, or by the process handles array being deleted due to the process dying,
	// all of which happen before $LOCK is deleted.
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::RemoveChunk %08x from %08x",aChunk,this));
	Kern::MutexWait(*iProcessLock);
	TInt pos=0;
	TInt r=ChunkIndex(aChunk,pos);
	__KTRACE_OPT(KPROC,if(r) Kern::Printf("Chunk lookup failed with %d",r));
	if (r==0) // Found the chunk
		{
		__KTRACE_OPT(KPROC,Kern::Printf("Chunk access count %d",iChunks[pos].iAccessCount));
		if (--iChunks[pos].iAccessCount==0)
			DoRemoveChunk(pos);
		}
	Kern::MutexSignal(*iProcessLock);
	}
コード例 #6
0
ファイル: mprocess.cpp プロジェクト: kuailexs/symbiandump-os1
TInt DMemModelProcess::AddChunk(DChunk* aChunk,TBool isReadOnly)
	{
	DMemModelChunk* pC=(DMemModelChunk*)aChunk;
	TInt r=WaitProcessLock();
	if (r==KErrNone)
		{
		TInt pos=0;
		r=ChunkIndex(pC,pos);
		TLinAddr dataSectionBase=0;
		if (r==0) // Found the chunk in this process, just up its count
			{
			iChunks[pos].iAccessCount++;
			__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::AddChunk %08x to %08x (Access count incremented to %d)",aChunk,this,iChunks[pos].iAccessCount));
			SignalProcessLock();
			return KErrNone;
			}
		r=AddChunk(pC,dataSectionBase,isReadOnly);
		SignalProcessLock();
		}
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::AddChunk returns %d",r));
	return r;
	}
コード例 #7
0
ファイル: mprocess.cpp プロジェクト: kuailexs/symbiandump-os1
TInt DMemModelProcess::AddChunk(DChunk* aChunk, TBool aIsReadOnly)
	{
	DMemModelChunk* pC=(DMemModelChunk*)aChunk;
	if(pC->iOwningProcess && this!=pC->iOwningProcess)
		return KErrAccessDenied;

	TInt r = WaitProcessLock();
	if(r==KErrNone)
		{
		TInt i = ChunkIndex(pC);
		if(i>=0) // Found the chunk in this process, just up its count
			{
			iChunks[i].iAccessCount++;
			__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::AddChunk %08x to %08x (Access count incremented to %d)",aChunk,this,iChunks[i].iAccessCount));
			SignalProcessLock();
			return KErrNone;
			}
		r = DoAddChunk(pC,aIsReadOnly);
		SignalProcessLock();
		}
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::AddChunk returns %d",r));
	return r;
	}
コード例 #8
0
ファイル: mprocess.cpp プロジェクト: kuailexs/symbiandump-os1
TInt DMemModelProcess::DoAddChunk(DMemModelChunk* aChunk, TBool aIsReadOnly)
	{
	//
	// Must hold the process $LOCK mutex before calling this.
	// As the process lock is held it is safe to access iOsAsid without a reference.
	//

	__NK_ASSERT_DEBUG(ChunkIndex(aChunk)==KErrNotFound); // shouldn't be adding a chunk which is already added

	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::DoAddChunk %O to %O",aChunk,this));

	// create mapping for chunk...
	DMemoryMapping* mapping;
	TMappingPermissions perm = MM::MappingPermissions
		(
		iOsAsid!=(TInt)KKernelOsAsid,	// user?
		aIsReadOnly==false, // write?
		aChunk->iAttributes&DMemModelChunk::ECode // execute?
		);
	TInt r;
	if(aChunk->iFixedBase) // HACK, kernel chunk has a fixed iBase
		r = MM::MappingNew(mapping,aChunk->iMemoryObject,perm,iOsAsid,EMappingCreateExactVirtual,(TLinAddr)aChunk->iFixedBase);
	else
		r = MM::MappingNew(mapping,aChunk->iMemoryObject,perm,iOsAsid);
	if(r!=KErrNone)
		return r;
	if(iOsAsid==0)
		aChunk->iKernelMapping = mapping;
	TLinAddr base = MM::MappingBase(mapping);

	// expand chunk info memory if required...
	if(iChunkCount==iChunkAlloc)
		{
		TInt newAlloc = iChunkAlloc+KChunkGranularity;
		r = Kern::SafeReAlloc((TAny*&)iChunks,iChunkAlloc*sizeof(SChunkInfo),newAlloc*sizeof(SChunkInfo));
		if(r!=KErrNone)
			{
			MM::MappingDestroy(mapping);
			return r;
			}
		iChunkAlloc = newAlloc;
		}

	// insert new chunk info...
	TUint i = ChunkInsertIndex(aChunk);
	SChunkInfo* info = iChunks+i;
	SChunkInfo* infoEnd = iChunks+iChunkCount;
	NKern::LockSystem();
	++iChunkCount;
	for(;;)
		{
		// make space for new chunk info by shuffling along
		// existing infos KMaxChunkInfosInOneGo at a time...
		SChunkInfo* infoPtr = infoEnd-KMaxChunkInfosInOneGo;
		if(infoPtr<info)
			infoPtr = info;
		memmove(infoPtr+1,infoPtr,(TLinAddr)infoEnd-(TLinAddr)infoPtr);
		infoEnd = infoPtr;
		if(infoEnd<=info)
			break;
		NKern::FlashSystem();
		}
	info->iChunk = aChunk;
	info->iMapping = mapping;
	info->iAccessCount = 1;
	info->iIsReadOnly = aIsReadOnly;
	NKern::UnlockSystem();

	// add chunk to list of Shared Chunks...
	if(aChunk->iChunkType==ESharedKernelSingle || aChunk->iChunkType==ESharedKernelMultiple)
		{
		if(!iSharedChunks)
			iSharedChunks = new RAddressedContainer(&TheSharedChunkLock,iProcessLock);
		if(!iSharedChunks)
			r = KErrNoMemory;
		else
			r = iSharedChunks->Add(base,aChunk);
		if(r!=KErrNone)
			{
			DoRemoveChunk(i);
			return r;
			}
		}

	// done OK...
	__DEBUG_EVENT(EEventUpdateProcess, this);
	return KErrNone;
	}