File Annotation

Not logged in
dcdd144598 2011-02-23        kinaba: #include "stdafx.h"
dcdd144598 2011-02-23        kinaba: #include "memory.h"
dcdd144598 2011-02-23        kinaba: using namespace ki;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #ifdef SUPERTINY
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	static HANDLE g_heap;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	#ifndef _DEBUG
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		void* __cdecl operator new( size_t siz )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			return ::HeapAlloc( g_heap, HEAP_GENERATE_EXCEPTIONS, siz );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		void __cdecl operator delete( void* ptr )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			::HeapFree( g_heap, 0, ptr );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	#else
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// デバッグ用に回数計測版(^^;
dcdd144598 2011-02-23        kinaba: 		static int allocCounter = 0;
dcdd144598 2011-02-23        kinaba: 		void* __cdecl operator new( size_t siz )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			++allocCounter;
dcdd144598 2011-02-23        kinaba: 			return ::HeapAlloc( g_heap, HEAP_GENERATE_EXCEPTIONS, siz );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		void __cdecl operator delete( void* ptr )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			::HeapFree( g_heap, 0, ptr );
dcdd144598 2011-02-23        kinaba: 			if( ptr != NULL )
dcdd144598 2011-02-23        kinaba: 				--allocCounter;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	#endif
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	extern "C"
dcdd144598 2011-02-23        kinaba: 	void* __cdecl memset( void* buf, int ch, size_t n )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		BYTE v = BYTE(ch&0xff);
dcdd144598 2011-02-23        kinaba: 		BYTE* ptr = (BYTE*)buf;
dcdd144598 2011-02-23        kinaba: 		DWORD vvvv = (v<<24) | (v<<16) | (v<<8) | v;
dcdd144598 2011-02-23        kinaba: 		for(;n>3;n-=4,ptr+=4) *(DWORD*)ptr = vvvv;
dcdd144598 2011-02-23        kinaba: 		for(;n;--n,++ptr) *ptr = v;
dcdd144598 2011-02-23        kinaba: 		return buf;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void* __cdecl memmove( void* dst, const void* src, size_t cnt )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		__asm {
dcdd144598 2011-02-23        kinaba: 			mov  esi, [src]    ;U  esi = const void* src
dcdd144598 2011-02-23        kinaba: 			mov  edx, [cnt]    ;V  edx =       void* cnt
dcdd144598 2011-02-23        kinaba: 			mov  edi, [dst]    ;U  edi =       ulong dst
dcdd144598 2011-02-23        kinaba: 			mov  ebx, edx      ;V
dcdd144598 2011-02-23        kinaba: 			mov  eax, 03h      ;U  eax = const ulong  3 (for masking)
dcdd144598 2011-02-23        kinaba: 			add  ebx, esi      ;V  ebx = const void* src+cnt
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			cmp  edi, esi      ;
dcdd144598 2011-02-23        kinaba: 			jbe  CopyUp        ;
dcdd144598 2011-02-23        kinaba: 			cmp  edi, ebx      ;   if( src < dst < src+cnt )
dcdd144598 2011-02-23        kinaba: 			jb   CopyDown      ;     downward copy
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		CopyUp:
dcdd144598 2011-02-23        kinaba: 			cmp  edx, eax      ;   if( cnt<=3 )
dcdd144598 2011-02-23        kinaba: 			jbe  MiniCopy      ;     byte by byte copy
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			mov  ebx, edi      ;U
dcdd144598 2011-02-23        kinaba: 			mov  ecx, eax      ;V
dcdd144598 2011-02-23        kinaba: 			and  ebx, eax      ;U  ebx = (dst&3)
dcdd144598 2011-02-23        kinaba: 			inc  ecx           ;V
dcdd144598 2011-02-23        kinaba: 			sub  ecx, ebx      ;   ecx = (4-(dst&3))
dcdd144598 2011-02-23        kinaba: 			and  ecx, eax      ;   ecx = {dst%4 0->0 1->3 2->2 3->1}
dcdd144598 2011-02-23        kinaba: 			sub  edx, ecx      ;
dcdd144598 2011-02-23        kinaba: 			rep  movsb         ;N  BYTE MOVE (align dst)
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			mov  ecx, edx      ;
dcdd144598 2011-02-23        kinaba: 			shr  ecx, 2        ;   ecx = [rest bytes]/4
dcdd144598 2011-02-23        kinaba: 			and  edx, eax      ;   edx = [rest bytes]%4
dcdd144598 2011-02-23        kinaba: 			rep  movsd         ;N  DWORD MOVE
dcdd144598 2011-02-23        kinaba: 			jmp  MiniCopy      ;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		CopyDown:
dcdd144598 2011-02-23        kinaba: 			std                  ;
dcdd144598 2011-02-23        kinaba: 			lea  esi,[esi+edx-1] ;
dcdd144598 2011-02-23        kinaba: 			lea  edi,[edi+edx-1] ;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			cmp  edx, 4        ;   if( cnt<=4 )
dcdd144598 2011-02-23        kinaba: 			jbe  MiniCopy      ;     byte by byte copy
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			mov  ecx, edi      ;
dcdd144598 2011-02-23        kinaba: 			and  ecx, eax      ;
dcdd144598 2011-02-23        kinaba: 			inc  ecx           ;   ecx = {dst%4 0->1 1->2 2->3 3->4}
dcdd144598 2011-02-23        kinaba: 			sub  edx, ecx      ;
dcdd144598 2011-02-23        kinaba: 			rep  movsb         ;N  BYTE MOVE (align dst @ dword)
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			sub  edi, eax      ;U
dcdd144598 2011-02-23        kinaba: 			mov  ecx, edx      ;V
dcdd144598 2011-02-23        kinaba: 			sub  esi, eax      ;U
dcdd144598 2011-02-23        kinaba: 			shr  ecx, 2        ;V  ecx = [rest bytes]/4
dcdd144598 2011-02-23        kinaba: 			and  edx, eax      ;   edx = [rest bytes]%4
dcdd144598 2011-02-23        kinaba: 			rep  movsd         ;N  DWORD MOVE
dcdd144598 2011-02-23        kinaba: 			add  edi, eax      ;U
dcdd144598 2011-02-23        kinaba: 			add  esi, eax      ;V
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		MiniCopy:
dcdd144598 2011-02-23        kinaba: 			mov  ecx, edx      ;
dcdd144598 2011-02-23        kinaba: 			rep  movsb         ;N  BYTE MOVE
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			cld                ;U
dcdd144598 2011-02-23        kinaba: 			mov  eax, [dst]    ;V  return dst
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		return dst;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #ifdef USE_ORIGINAL_MEMMAN
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //	効率的なメモリ管理を目指すアロケータ
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // メモリブロック
dcdd144598 2011-02-23        kinaba: // 「sizバイト * num個」分の領域を一括確保するのが仕事
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // 空きブロックには、先頭バイトに [次の空きブロックのindex] を格納。
dcdd144598 2011-02-23        kinaba: // これを用いて、先頭への出し入れのみが可能な単方向リストとして扱う。
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct ki::MemBlock
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 	void  Construct( byte siz, byte num );
dcdd144598 2011-02-23        kinaba: 	void  Destruct();
dcdd144598 2011-02-23        kinaba: 	void* Alloc( byte siz );
dcdd144598 2011-02-23        kinaba: 	void  DeAlloc( void* ptr, byte siz );
dcdd144598 2011-02-23        kinaba: 	bool  isAvail();
dcdd144598 2011-02-23        kinaba: 	bool  isEmpty( byte num );
dcdd144598 2011-02-23        kinaba: 	bool  hasThisPtr( void* ptr, size_t len );
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	byte* buf_;
dcdd144598 2011-02-23        kinaba: 	byte  first_, avail_;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemBlock::Construct( byte siz, byte num )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 確保
dcdd144598 2011-02-23        kinaba: 	buf_   = ::new byte[siz*num];
dcdd144598 2011-02-23        kinaba: 	first_ = 0;
dcdd144598 2011-02-23        kinaba: 	avail_ = num;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 連結リスト初期化
dcdd144598 2011-02-23        kinaba: 	for( byte i=0,*p=buf_; i<num; p+=siz )
dcdd144598 2011-02-23        kinaba: 		*p = ++i;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void MemBlock::Destruct()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 解放
dcdd144598 2011-02-23        kinaba: 	::delete [] buf_;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void* MemBlock::Alloc( byte siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// メモリ切り出し
dcdd144598 2011-02-23        kinaba: 	//   ( avail==0 等のチェックは上位層に任せる )
dcdd144598 2011-02-23        kinaba: 	byte* blk = buf_ + siz*first_;
dcdd144598 2011-02-23        kinaba: 	first_    = *blk;
dcdd144598 2011-02-23        kinaba: 	--avail_;
dcdd144598 2011-02-23        kinaba: 	return blk;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemBlock::DeAlloc( void* ptr, byte siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// メモリ戻す
dcdd144598 2011-02-23        kinaba: 	//   ( 変なポインタ渡されたらだ〜め〜 )
dcdd144598 2011-02-23        kinaba: 	byte* blk = static_cast<byte*>(ptr);
dcdd144598 2011-02-23        kinaba: 	*blk      = first_;
dcdd144598 2011-02-23        kinaba: 	first_    = static_cast<byte>((blk-buf_)/siz);
dcdd144598 2011-02-23        kinaba: 	++avail_;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline bool MemBlock::isAvail()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 空きがある?
dcdd144598 2011-02-23        kinaba: 	return (avail_ != 0);
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline bool MemBlock::isEmpty( byte num )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 完全に空?
dcdd144598 2011-02-23        kinaba: 	return (avail_ == num);
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline bool MemBlock::hasThisPtr( void* ptr, size_t len )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// このブロックのポインタ?
dcdd144598 2011-02-23        kinaba: 	return ( buf_<=ptr && ptr<buf_+len );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // 固定サイズ確保人
dcdd144598 2011-02-23        kinaba: // 「sizバイト」の領域を毎回確保するのが仕事
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // メモリブロックのリストを保持し、空いているブロックを使って
dcdd144598 2011-02-23        kinaba: // メモリ要求に応えていく。空きがなくなったら新しくMemBlockを
dcdd144598 2011-02-23        kinaba: // 作ってリストに加える。
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // 最後にメモリ割り当て/解放を行ったBlockをそれぞれ記憶しておき、
dcdd144598 2011-02-23        kinaba: // 最初にそこを調べることで高速化を図る。
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemoryManager::FixedSizeMemBlockPool::Construct( byte siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// メモリマネージャが初期化されるまでは、
dcdd144598 2011-02-23        kinaba: 	// 普通のauto_ptrも使わない方が無難…
dcdd144598 2011-02-23        kinaba: 	struct AutoDeleter
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		AutoDeleter( MemBlock* p ) : ptr_(p) {}
dcdd144598 2011-02-23        kinaba: 		~AutoDeleter() { ::delete [] ptr_; }
dcdd144598 2011-02-23        kinaba: 		void Release() { ptr_ = NULL; }
dcdd144598 2011-02-23        kinaba: 		MemBlock* ptr_;
dcdd144598 2011-02-23        kinaba: 	};
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// メモリブロック情報域をちょこっと確保
dcdd144598 2011-02-23        kinaba: 	AutoDeleter a( blocks_ = ::new MemBlock[4] );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// ブロックサイズ等計算
dcdd144598 2011-02-23        kinaba: 	int npb = BLOCK_SIZ/siz;
dcdd144598 2011-02-23        kinaba: 	numPerBlock_ = static_cast<byte>( Min( npb, 255 ) );
dcdd144598 2011-02-23        kinaba: 	fixedSize_   = siz;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 一個だけブロック作成
dcdd144598 2011-02-23        kinaba: 	blocks_[0].Construct( fixedSize_, numPerBlock_ );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	a.Release();
dcdd144598 2011-02-23        kinaba: 	lastA_            = 0;
dcdd144598 2011-02-23        kinaba: 	lastDA_           = 0;
dcdd144598 2011-02-23        kinaba: 	blockNum_         = 1;
dcdd144598 2011-02-23        kinaba: 	blockNumReserved_ = 4;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemoryManager::FixedSizeMemBlockPool::Destruct()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 各ブロックを解放
dcdd144598 2011-02-23        kinaba: 	for( int i=0; i<blockNum_; ++i )
dcdd144598 2011-02-23        kinaba: 		blocks_[i].Destruct();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// ブロック情報保持領域のメモリも解放
dcdd144598 2011-02-23        kinaba: 	::delete [] blocks_;
dcdd144598 2011-02-23        kinaba: 	blockNum_ = 0;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void* MemoryManager::FixedSizeMemBlockPool::Alloc()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// ここでlastA_がValidかどうかチェックしないとまずい。
dcdd144598 2011-02-23        kinaba: 	// DeAllocされてなくなってるかもしらないので。
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 前回メモリを切り出したブロックに
dcdd144598 2011-02-23        kinaba: 	// まだ空きがあるかどうかチェック
dcdd144598 2011-02-23        kinaba: 	if( !blocks_[lastA_].isAvail() )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// 無かった場合、リストの末尾から順に線形探索
dcdd144598 2011-02-23        kinaba: 		for( int i=blockNum_;; )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( blocks_[--i].isAvail() )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// 空きブロック発見〜!
dcdd144598 2011-02-23        kinaba: 				lastA_ = i;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			if( i == 0 )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// 全部埋まってた...
dcdd144598 2011-02-23        kinaba: 				if( blockNum_ == blockNumReserved_ )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					// しかも作業領域も満杯なので拡張
dcdd144598 2011-02-23        kinaba: 					MemBlock* nb = ::new MemBlock[ blockNum_*2 ];
dcdd144598 2011-02-23        kinaba: 					memmove( nb, blocks_, sizeof(MemBlock)*(blockNum_) );
dcdd144598 2011-02-23        kinaba: 					::delete [] blocks_;
dcdd144598 2011-02-23        kinaba: 					blocks_ = nb;
dcdd144598 2011-02-23        kinaba: 					blockNumReserved_ *= 2;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// 新しくブロック構築
dcdd144598 2011-02-23        kinaba: 				blocks_[ blockNum_ ].Construct( fixedSize_, numPerBlock_ );
dcdd144598 2011-02-23        kinaba: 				lastA_ = blockNum_++;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// ブロックから切り出し割り当て
dcdd144598 2011-02-23        kinaba: 	return blocks_[lastA_].Alloc( fixedSize_ );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemoryManager::FixedSizeMemBlockPool::DeAlloc( void* ptr )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 該当ブロックを探索
dcdd144598 2011-02-23        kinaba: 	const int mx=blockNum_, ln=fixedSize_*numPerBlock_;
dcdd144598 2011-02-23        kinaba: 	for( int u=lastDA_, d=lastDA_-1;; )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( u>=0 )
dcdd144598 2011-02-23        kinaba: 			if( blocks_[u].hasThisPtr(ptr,ln) )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				lastDA_ = u;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else if( u==mx )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				u = -1;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				++u;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		if( d>=0 )
dcdd144598 2011-02-23        kinaba: 			if( blocks_[d].hasThisPtr(ptr,ln) )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				lastDA_ = d;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				--d;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 解放を実行
dcdd144598 2011-02-23        kinaba: 	blocks_[lastDA_].DeAlloc( ptr, fixedSize_ );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// この削除でブロックが完全に空になった場合
dcdd144598 2011-02-23        kinaba: 	if( blocks_[lastDA_].isEmpty( numPerBlock_ ) )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// しかも一番後ろのブロックでなかったら
dcdd144598 2011-02-23        kinaba: 		int end = blockNum_-1;
dcdd144598 2011-02-23        kinaba: 		if( lastDA_ != end )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			// 一番後ろが空だったら解放
dcdd144598 2011-02-23        kinaba: 			if( blocks_[end].isEmpty( numPerBlock_ ) )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				blocks_[end].Destruct();
dcdd144598 2011-02-23        kinaba: 				--blockNum_;
dcdd144598 2011-02-23        kinaba: 				if( lastA_ > --end )
dcdd144598 2011-02-23        kinaba: 					lastA_ = end;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// 後ろと交換
dcdd144598 2011-02-23        kinaba: 			MemBlock tmp( blocks_[lastDA_] );
dcdd144598 2011-02-23        kinaba: 			blocks_[lastDA_] = blocks_[end];
dcdd144598 2011-02-23        kinaba: 			blocks_[end]     = tmp;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline bool MemoryManager::FixedSizeMemBlockPool::isValid()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 既に使用開始されているか?
dcdd144598 2011-02-23        kinaba: 	return (blockNum_ != 0);
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // 最上位層
dcdd144598 2011-02-23        kinaba: // 指定サイズにあった FixedSizeMemBlockPool に処理をまわす
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: // lokiの実装では固定サイズアロケータも、必要に応じて
dcdd144598 2011-02-23        kinaba: // 動的確保していたが、それは面倒なのでやめました。(^^;
dcdd144598 2011-02-23        kinaba: // 最初に64個確保したからと言って、そんなにメモリも喰わないし…。
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: MemoryManager* MemoryManager::pUniqueInstance_;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: MemoryManager::MemoryManager()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	g_heap = ::GetProcessHeap();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// メモリプールをZEROクリア
dcdd144598 2011-02-23        kinaba: 	mem00( pools_, sizeof(pools_) );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 唯一のインスタンスは私です
dcdd144598 2011-02-23        kinaba: 	pUniqueInstance_ = this;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: MemoryManager::~MemoryManager()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 構築済みメモリプールを全て解放
dcdd144598 2011-02-23        kinaba: 	for( int i=0; i<SMALL_MAX; ++i )
dcdd144598 2011-02-23        kinaba: 		if( pools_[i].isValid() )
dcdd144598 2011-02-23        kinaba: 			pools_[i].Destruct();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #if defined(SUPERTINY) && defined(_DEBUG)
dcdd144598 2011-02-23        kinaba: 	// リーク検出用
dcdd144598 2011-02-23        kinaba: 	if( allocCounter != 0 )
dcdd144598 2011-02-23        kinaba: 		::MessageBox( NULL, TEXT("MemoryLeak!"), NULL, MB_OK );
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void* MemoryManager::Alloc( size_t siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: #if defined(SUPERTINY) && defined(_DEBUG)
dcdd144598 2011-02-23        kinaba: 	++allocCounter;
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// サイズが零か大きすぎるなら
dcdd144598 2011-02-23        kinaba: 	// デフォルトの new 演算子に任せる
dcdd144598 2011-02-23        kinaba: 	uint i = static_cast<uint>( siz-1 );
dcdd144598 2011-02-23        kinaba: 	if( i >= SMALL_MAX )
dcdd144598 2011-02-23        kinaba: 		return ::operator new( siz );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// マルチスレッド対応
dcdd144598 2011-02-23        kinaba: 	AutoLock al(this);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// このサイズのメモリ確保が初めてなら
dcdd144598 2011-02-23        kinaba: 	// ここでメモリプールを作成する。
dcdd144598 2011-02-23        kinaba: 	if( !pools_[i].isValid() )
dcdd144598 2011-02-23        kinaba: 		pools_[i].Construct( static_cast<byte>(siz) );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// ここで割り当て
dcdd144598 2011-02-23        kinaba: 	return pools_[i].Alloc();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemoryManager::DeAlloc( void* ptr, size_t siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: #if defined(SUPERTINY) && defined(_DEBUG)
dcdd144598 2011-02-23        kinaba: 	--allocCounter;
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// サイズが零か大きすぎるなら
dcdd144598 2011-02-23        kinaba: 	// デフォルトの delete 演算子に任せる
dcdd144598 2011-02-23        kinaba: 	uint i = static_cast<uint>( siz-1 );
dcdd144598 2011-02-23        kinaba: 	if( i >= SMALL_MAX )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		::operator delete( ptr );
dcdd144598 2011-02-23        kinaba: 		return; // VCで return void が出来ないとは…
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// マルチスレッド対応
dcdd144598 2011-02-23        kinaba: 	AutoLock al(this);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// ここで解放
dcdd144598 2011-02-23        kinaba: 	pools_[i].DeAlloc( ptr );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #else // USE_ORIGNAL_MEMMAN
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: MemoryManager* MemoryManager::pUniqueInstance_;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: MemoryManager::MemoryManager()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	g_heap = ::GetProcessHeap();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 唯一のインスタンスは私です
dcdd144598 2011-02-23        kinaba: 	pUniqueInstance_ = this;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: MemoryManager::~MemoryManager()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: #if defined(SUPERTINY) && defined(_DEBUG)
dcdd144598 2011-02-23        kinaba: 	// リーク検出用
dcdd144598 2011-02-23        kinaba: 	if( allocCounter != 0 )
dcdd144598 2011-02-23        kinaba: 		::MessageBox( NULL, TEXT("MemoryLeak!"), NULL, MB_OK );
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void* MemoryManager::Alloc( size_t siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	return ::operator new(siz);
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void MemoryManager::DeAlloc( void* ptr, size_t siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::operator delete(ptr);
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #endif