86 #define INVALID_TELL (ULONG_MAX)
105 WORD *index(
void) {
return reinterpret_cast<WORD*
>(m_pContent); }
109 return (m_pContent == NULL)
111 :
reinterpret_cast<WORD*
>(&m_pContent[
sizeof(WORD) * m_wSectorCount]);
114 BYTE* data(WORD wSecNo)
116 return (m_pContent == NULL)
118 : &m_pContent[
sizeof(WORD) * m_wSectorCount +
119 sizeof(WORD) * m_wSectorCount +
120 m_dwSectorSize * wSecNo];
123 WORD m_IndexToSecNo(WORD i)
126 ASSERTLIB(W[i] != 0);
127 return ToWord(W[i] & 0x7FFF);
137 DWORD m_AllocSub(WORD wStart, WORD wEnd, WORD wLen)
141 while ( wStart < wEnd )
143 wNext =
static_cast<WORD
>(F[wStart] & 0x7FFF);
146 wNext = m_wSectorCount;
148 if ( (F[wStart] & 0x8000) == 0 && (wNext - wStart) >= wLen )
151 WORD w =
static_cast<WORD
>(wStart + wLen);
152 if ( w >= m_wSectorCount )
156 for ( WORD i = 0; i < wLen; i++ )
158 F[wStart + i] =
static_cast<WORD
>(0x8000 | w);
183 if ( m_pContent != NULL )
190 WORD GetSectorCount(
void) {
return m_wSectorCount; }
192 bool IsValid(
void) {
return m_pContent != NULL; }
199 EResult Create(DWORD dwSectorSize, WORD wSectorCount)
204 if ( wSectorCount < 10 || wSectorCount >= 32768) {
return ER_InvalidParam; }
205 m_pContent =
new BYTE[
sizeof(WORD) * wSectorCount + (
sizeof(WORD) + dwSectorSize) * wSectorCount];
207 memset(m_pContent, 0,
sizeof(WORD) * wSectorCount +
sizeof(WORD) * wSectorCount);
208 m_dwSectorSize = dwSectorSize;
209 m_wSectorCount= wSectorCount;
217 if ( m_dwLockCount != 0 )
219 TRACE0(
"CStaticMemory::CManage::Delete() ; Lock/Unlockの回数が合っていません。\n");
222 if ( m_pContent != NULL )
238 EResult Resize(WORD wSectorCount)
241 if ( wSectorCount == 0 )
243 wSectorCount = m_wSectorCount;
245 else if ( m_wUsedSectors > wSectorCount )
249 else if ( m_wSectorCount > wSectorCount )
255 EResult rc = infoNew.Create(m_dwSectorSize, wSectorCount);
259 WORD* newW = infoNew.index();
262 for ( WORD i = 0; i < m_wSectorCount; i++ )
268 WORD wLen =
static_cast<WORD
>((F[wPos] & 0x7FFF) - wPos);
269 DWORD r = infoNew.m_AllocSub(infoNew.m_wCacheSecNo, wSectorCount, wLen);
272 r = infoNew.m_AllocSub(0, infoNew.m_wCacheSecNo, wLen);
275 BYTE* P = infoNew.data(ToWord(r));
276 ASSERTLIB(P != NULL);
277 MemCopy(P, data(wPos), wLen * m_dwSectorSize);
278 newW[i] = ToWord(0x8000 | r);
281 m_wSectorCount= wSectorCount;
285 m_pContent = infoNew.m_pContent;
286 infoNew.m_pContent = NULL;
292 WORD GetUsedSectors(
void)
294 return m_wUsedSectors;
306 WORD wLen = ToWord((
ToDword(size) + m_dwSectorSize - 1) / m_dwSectorSize);
307 if ( wLen + m_wUsedSectors > m_wSectorCount ){
return INVALID_TELL; }
308 DWORD r = m_AllocSub(m_wCacheSecNo, m_wSectorCount, wLen);
311 r = m_AllocSub(0, m_wCacheSecNo, wLen);
318 m_wUsedSectors =
static_cast<WORD
>(m_wUsedSectors + wLen);
320 for ( WORD i = m_wCacheIndex; i < m_wSectorCount; i++ )
324 W[i] = ToWord(0x8000 | r);
329 for ( WORD i = 0; i < m_wCacheIndex; i++ )
333 W[i] = ToWord(0x8000 | r);
347 bool Free(WORD wIndex)
350 if ( m_pContent == NULL ){
return false; }
351 if ( wIndex >= m_wSectorCount ){
return false; }
352 WORD wSecNo = m_IndexToSecNo(wIndex);
353 ASSERTLIB(wSecNo < m_wSectorCount);
355 if ( (F[wSecNo] & 0x8000) == 0 ){
return false; }
356 m_wCacheSecNo = wSecNo;
358 WORD wNext =
static_cast<WORD
>(F[wSecNo] & 0x7FFF);
362 wNext = m_wSectorCount;
368 if ( (F[wNext] & 0x8000) != 0 )
379 for ( WORD i = wSecNo; i < wNext; i++ )
384 m_wCacheIndex = wIndex;
385 m_wUsedSectors =
static_cast<WORD
>(m_wUsedSectors - (wNext - wSecNo));
400 WORD wSecNo = m_IndexToSecNo(wIndex);
401 ASSERTLIB(wSecNo < m_wSectorCount);
403 if ( (F[wSecNo] & 0x8000) == 0 ){
return INVALID_TELL; }
406 if ( F[wSecNo - 1] == F[wSecNo] ){
return INVALID_TELL; }
408 return ((F[wSecNo] & 0x7FFF) - wSecNo) * m_dwSectorSize;
414 DWORD GetLockCount(
void) {
return m_dwLockCount; }
422 LPVOID
Lock(WORD wIndex)
426 WORD wSecNo = m_IndexToSecNo(wIndex);
427 ASSERTLIB(wSecNo < m_wSectorCount);
428 ASSERT0(data(wSecNo) != NULL,
"CStaticMemory::CManage::CInfo::Lock()",
"確保していません");
442 friend class CStaticMemoryTest;
451 m_pInfo =
new CInfo[256];
452 ASSERT( m_pInfo != NULL );
459 bool m_CheckTell(TELL& tell, BYTE& bank)
461 bank =
static_cast<BYTE
>(tell >> 24);
463 if ( ! m_pInfo[bank].IsValid() ){
return false; }
464 return m_pInfo[bank].GetSectorCount() > tell;
470 if ( m_pInfo != NULL )
487 return m_pInfo[bank].Create(dwSectorSize, wSectorCount);
499 EXCLUSIVE2(&m_syncFunc,&m_pInfo[bank].syncBank);
501 if ( ! boIsForce && m_pInfo[bank].GetLockCount() != 0 ){
return ER_Locked; }
502 m_pInfo[bank].Delete();
516 EXCLUSIVE2(&m_syncFunc,&m_pInfo[bank].syncBank);
518 if ( m_pInfo[bank].GetLockCount() != 0 ){
return ER_Locked; }
519 return m_pInfo[bank].Resize(wSectorCount);
528 WORD GetUsedSectors(BYTE bank)
530 return static_cast<WORD
>(m_pInfo[bank].IsValid() ? m_pInfo[bank].GetUsedSectors() : 0);
540 TELL
Allocate(BYTE bank,
size_t size)
542 if ( size == 0 || ! m_pInfo[bank].IsValid() ){
return INVALID_TELL; }
543 DWORD dw = m_pInfo[bank].Allocate(size);
555 return m_CheckTell(tell, bank) ? m_pInfo[bank].Free(ToWord(tell)) :
false;
567 return m_CheckTell(tell, bank) ? m_pInfo[bank].GetSize(ToWord(tell)) : 0;
577 LPVOID
Lock(TELL tell)
580 return m_CheckTell(tell, bank) ? m_pInfo[bank].Lock(ToWord(tell)) : NULL;
592 if ( ! m_CheckTell(tell, bank) ){
return false; }
593 m_pInfo[bank].Unlock();
598 friend class CStaticMemoryTest;
610 m_pMan = CManage::GetInstance();
630 return CManage::GetInstance()->CreateBank(bank, dwSectorSize, wSectorCount);
645 return CManage::GetInstance()->DeleteBank(bank, boIsForce);
664 return CManage::GetInstance()->ResizeBank(bank, wSectorCount);
699 LONG* B =
static_cast<LONG*
>(m_pMan->Lock(other.m_tell));
700 ::InterlockedIncrement(B);
701 m_pMan->Unlock(other.m_tell);
702 m_tell = other.m_tell;
704 m_dwParam = other.m_dwParam;
736 LONG* B =
static_cast<LONG*
>(m_pMan->Lock(m_tell));
738 m_pMan->Unlock(m_tell);
764 TELL t = m_pMan->Allocate(bank, size +
sizeof(LONG));
769 LONG* P =
static_cast<LONG*
>(m_pMan->Lock(t));
789 LONG* B =
static_cast<LONG*
>(m_pMan->Lock(m_tell));
790 if ( ::InterlockedDecrement(B) == 0 )
792 m_pMan->Unlock(m_tell);
793 m_pMan->Free(m_tell);
797 m_pMan->Unlock(m_tell);
811 size_t l = m_pMan->GetSize(m_tell);
828 LONG* B =
static_cast<LONG*
>(m_pMan->Lock(m_tell));
840 m_pMan->Unlock(m_tell);
845 friend class CStaticMemoryTest;
857 [Indexテーブル][Flagテーブル][内容]という並び。
860 TELLの下位WORD(Index)とセクタNoを関連付けるテーブル。最上位BIT
861 が立っていたら使用(下位15BITがSecNo)
862 Resize、デフラグしても並びは変換しない。
867 Flag用は、次の空きセクタ番号を保持。0なら最後を指す。
869 確保すると、複数の確保したセクタすべて最上位ビットが立ち、
872 <0> <1> <2> <3> <4> <5> <6>
874 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
876 0x8002,0x8002,0x0000,0x0000,0x0000,0x0000,0x0000,
878 0x8002,0x8002,0x8005,0x8005,0x8005,0x0000,0x0000,
880 0x0002,0x0002,0x8005,0x8005,0x8005,0x0000,0x0000,
882 0x8001,0x0002,0x8005,0x8005,0x8005,0x0000,0x0000,
884 つまりチェーンと使用フラグとブロック長がわかるようになる。
#define INVALID_TELL
静的メモリ管理クラス用エラー値宣言
CStaticMemory & operator=(const CStaticMemory &other)
[代入] コピーオペレータ
size_t GetSize(void)
[取得] 確保サイズ取得
void Unlock(void)
[取得] アンロック
bool Allocate(BYTE bank, size_t size)
[取得] メモリ確保
CStaticMemory(void)
コンストラクタ
static EResult ResizeBank(BYTE bank, WORD wSectorCount=0)
[設定] バンクのりサイズ.
DWORD GetParam(void)
[取得] パラメータ取得
~CStaticMemory(void)
デストラクタ
CStaticMemory(const CStaticMemory &h)
コピーコンストラクタ
@ ER_InvalidTell
不正なTELLです。
@ ER_ExistBank
すでにバンクがあります。
@ ER_InvalidParam
不正なパラメータです。
@ ER_NotFoundBank
バンクが見つかりません。
@ ER_OutOfMemory
メモリが足りません。
static EResult DeleteBank(BYTE bank, bool boIsForce=false)
[設定] バンク削除.
bool HasMemory(void)
[確認] メモリ保持確認
LONG GetJointlyCount(void)
[取得] 共有数取得.
LPVOID Lock(void)
[取得] アドレス取得&ロック.
void SetParam(DWORD dwParam)
[代入] パラメータ設定
static EResult CreateBank(BYTE bank, DWORD dwSectorSize, WORD wSectorCount)
[設定] バンク作成.
void Free(void)
[取得] メモリ解放
#define SINGLETON_CONSTRUCTOR(CLS)
シングルトン作成マクロ
DWORD ToDword(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
#define EXCLUSIVE2(CLS1, CLS2)
簡易排他ツイン制御マクロ.
#define EXCLUSIVE(CLS)
簡易排他制御マクロ.
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー