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