private void ChangeAddress(ref TMemNode Target, TMemNode New, int Size) { New.Previous = Target.Previous; New.Next = Target.Next; New.Size = Size; if (New.Previous != null) { System.Diagnostics.Debug.Assert(New.Previous.Next == Target); New.Previous.Next = New; } if (New.Next != null) { System.Diagnostics.Debug.Assert(New.Next.Previous == Target); New.Next.Previous = New; } if (m_FreeMem.First == Target) { m_FreeMem.First = New; } if (m_FreeMem.Last == Target) { m_FreeMem.Last = New; } Target = New; }
public void Remove(TMemNode Item) { if (First == Item) { First = Item.Next; } if (Last == Item) { Last = Item.Previous; } //削除するノードの関連付けを次のノードに設定 if (Item.Previous != null) { Item.Previous.Next = Item.Next; } //削除するノードの関連付けを前のノードに設定 if (Item.Next != null) { Item.Next.Previous = Item.Previous; } Count--; //削除したノードを返して終了 Item.Previous = null; Item.Next = null; }
public void AddLast(TMemNode Item) { //キューにまだノードが一つも無い場合 if (Last == null) { //System.Diagnostics.Debug.Assert(Count == 0); //新しいItemの前のItemはなしに設定 Item.Previous = null; //新しいItemを最初のItemに設定 First = Item; } else { //最後のItemの次は新しいItemに設定 Last.Next = Item; //新しいItemを最後のItemの前のItemに設定 Item.Previous = Last; } //新しいItemを最後のItemに設定 Last = Item; //新しいItemの次のItemはなしに設定 Item.Next = null; Count++; }
public TMemNode(pointer data, int size) : base(data) { #if DEBUG m_Header = new _CrtMemBlockHeader(this, 0, null, null, "", 0, size, _CrtMemBlockHeader._NORMAL_BLOCK, 0); #endif Previous = null; Next = null; Size = size; }
public ER GetMemoryBlock(out pointer p_blk, int blksz, TMO tmout) { ER ret; p_blk = null; //if (p_blk == null) // return ER.E_PAR; for (; ;) { TMemNode Node = Allocate(blksz); if (Node != null) { p_blk = Node.GetData(); break; } if (tmout == 0) { return(ER.E_TMOUT); } Task task = m_Nucleus.GetTask(ID.TSK_SELF); if (task == null) { return(ER.E_CTX); } task.MemoryBlockSize = blksz; ret = task.Wait(m_TskQueue, TSKWAIT.TTW_MPL, m_MplID, tmout); switch (ret) { case ER.E_OK: continue; case ER.E_TMOUT: return(ER.E_TMOUT); default: return(ER.E_RLWAI); } } #if DEBUG string lpszFileName = ""; int nLine = 0; _CrtMemBlockHeader.AddBlock(m_pFirstBlock, m_pLastBlock, p_blk, blksz, lpszFileName, nLine); m_nBlockCount++; #endif return(ER.E_OK); }
public void AddBefore(TMemNode Pos, TMemNode Item) { //キューにまだノードが一つも無い場合 if (First == null) { //System.Diagnostics.Debug.Assert(Count == 0); //新しいItemの次のItemはなしに設定 Item.Next = null; //新しいItemを最後のItemに設定 Last = Item; //新しいItemを最初のItemに設定 First = Item; //新しいItemの前のItemはなしに設定 Item.Previous = null; } else if (Pos == null) { //最初のItemの前は新しいItemに設定 First.Previous = Item; //新しいItemを最初のItemの次のItemに設定 Item.Next = First; //新しいItemを最初のItemに設定 First = Item; //新しいItemの前のItemはなしに設定 Item.Previous = null; } else { Item.Previous = Pos.Previous; Item.Next = Pos; if (Pos.Previous != null) { Pos.Previous.Next = Item; } else { First = Item; } Pos.Previous = Item; Count++; } }
public MemoryPool(ID mplid, ref T_CMPL pk_cmpl, Nucleus pNucleus) { TMemNode Block = new TMemNode(pk_cmpl.addr, pk_cmpl.mplsz); m_MplID = mplid; m_cmpl = pk_cmpl; m_Nucleus = pNucleus; m_MaxSize = pk_cmpl.mplsz; m_FreeSize = pk_cmpl.mplsz; m_FreeMem.AddLast(Block); #if DEBUG m_pFirstBlock = null; m_pLastBlock = null; m_nBlockCount = 0; m_Dumped = false; #endif }
public void UpdateFreeSize() { int Max = 0; int Total = 0; for (TMemNode Node = m_FreeMem.First; Node != null; Node = Node.Next) { int Size = Node.Size; if (Max < Size) { Max = Size; } Total += Size; } m_MaxSize = Max; m_FreeSize = Total; }
public ER ReleaseMemoryBlock(pointer blk) { if (blk == null) { return(ER.E_PAR); } //if ((int)blk != 0) // return ER.E_PAR; System.Diagnostics.Debug.Assert((blk >= m_cmpl.addr) && (blk < m_cmpl.addr + m_cmpl.mplsz)); #if DEBUG _CrtMemBlockHeader.DelBlock(m_pFirstBlock, m_pLastBlock, blk); m_nBlockCount--; #endif TMemNode Mem = TMemNode.GetNode(blk); if (!Free(Mem)) { return(ER.E_PAR); } UpdateFreeSize(); #if DEBUG pointer.memset(Mem + 1, 0xDD, Mem.Size - TMemNode.length); #endif for (LinkedListNode <Task> Node = m_TskQueue.First; Node != null; Node = Node.Next) { Task task = Node.Value; if (task.MemoryBlockSize <= m_MaxSize) { m_TskQueue.Remove(Node); if (!task.ReleaseWait()) { return(ER.E_RLWAI); } } } return(ER.E_OK); }
private TMemNode Allocate(TMemNode Node, int Size) { TMemNode FreeMem = Node; TMemNode Result; // 取得サイズが空き領域に対してある程度小さい場合 if (Size < FreeMem.Size / 8) { // 空き領域の先頭から割り当て Result = FreeMem; ChangeAddress(ref FreeMem, new TMemNode(new pointer(FreeMem, Size), FreeMem.Size - Size), FreeMem.Size - Size); Result = new TMemNode(Result, Size); } // 大きい場合 else { // 空き領域の末尾から割り当て FreeMem.Size = FreeMem.Size - Size; Result = new TMemNode(new pointer(FreeMem, FreeMem.Size), Size); } return(Result); }
private TMemNode Allocate(int Size) { TMemNode Node, Temp; int Pad; // サイズ制限 if (Size < TMemNode.GetMinimumSize()) { Size = TMemNode.GetMinimumSize(); } Size += TMemNode.GetHeaderSize() + TMemNode.GetFooterSize(); // アライメント調整 Pad = Size & 0x3; if (Pad != 0) { Size += 4 - Pad; } // 取得サイズが空き領域に対してある程度小さい場合 if (Size < m_cmpl.mplsz / 8) { // 空き領域リストの先頭から検索 Temp = m_FreeMem.First; while (Temp != null) { Node = Temp; Temp = Node.Next; // 取得サイズより大きい空き領域の場合 if (Size < Node.Size) { // 空き領域からメモリ取得 return(Allocate(Node, Size)); } // 取得サイズと等しい空き領域の場合 else if (Size == Node.Size) { m_FreeMem.Remove(Node); return(new TMemNode(Node, Size)); } } } // 大きい場合 else { // 空き領域リストの末尾から検索 Temp = m_FreeMem.Last; while (Temp != null) { Node = Temp; Temp = Node.Previous; // 取得サイズより大きい空き領域の場合 if (Size < Node.Size) { // 空き領域からメモリ取得 return(Allocate(Node, Size)); } // 取得サイズと等しい空き領域の場合 else if (Size == Node.Size) { m_FreeMem.Remove(Node); return(new TMemNode(Node, Size)); } } } #if DEBUG if (!m_Dumped) { m_Nucleus.EnumMemoryBlock(this); m_Dumped = true; } #endif return(null); }
private bool Free(TMemNode Mem) { TMemNode Node; TMemNode FreeMem; pointer NextAddress = ((pointer)Mem) + Mem.Size; int FreeNextAddress; // 解放メモリサイズが空き領域に対してある程度小さい場合 if (Mem.Size < m_cmpl.mplsz / 8) { // 空き領域リストの先頭から検索 TMemNode Next; TMemNode NextFreeMem; // 解放メモリのアドレスが、管理領域の先頭より前の場合 if (Mem < m_cmpl.addr) { return false; } Next = m_FreeMem.First; while (Next != null) { Node = Next; Next = Node.Next; FreeMem = Node; FreeNextAddress = FreeMem.offset + FreeMem.Size; // 解放メモリが空き領域より前にある場合 if (NextAddress < FreeMem) { // 空き領域の前に解放メモリを空き領域として追加 m_FreeMem.AddBefore(Node, Mem); return true; } // 解放メモリのアドレスが空き領域の次のアドレスの場合 else if (Mem.offset == FreeNextAddress) { // 空き領域の後ろに解放メモリを融合 FreeMem.Size += Mem.Size; if (Next != null) { // 次の空き領域のアドレスが解放メモリの次のアドレスの場合 NextFreeMem = Next; if (NextAddress == ((pointer)NextFreeMem)) { // 空き領域に次の空き領域を融合 FreeMem.Size += NextFreeMem.Size; // 次の空き領域を削除 m_FreeMem.Remove(Next); } } return true; } // 空き領域の次のアドレスが解放メモリのアドレスの場合 else if (NextAddress == FreeMem) { // 空き領域の前に解放メモリを融合 ChangeAddress(ref FreeMem, Mem, FreeMem.Size + Mem.Size); return true; } // 解放メモリが不正の場合 else if (((Mem > FreeMem) && (Mem.offset < FreeNextAddress)) || ((NextAddress > FreeMem) && (NextAddress.offset < FreeNextAddress))) { return false; } } // 解放メモリのアドレスが、管理領域内の場合 if (NextAddress <= (m_cmpl.addr + m_cmpl.mplsz)) { // 空き領域リストの最後に解放メモリを空き領域として追加 m_FreeMem.AddLast(Mem); return true; } } // 大きい場合 else { // 空き領域リストの末尾から検索 TMemNode Prev; // 解放メモリのアドレスが、管理領域の末尾より後の場合 if (NextAddress > (m_cmpl.addr + m_cmpl.mplsz)) { return false; } Prev = m_FreeMem.Last; while (Prev != null) { Node = Prev; Prev = Node.Previous; FreeMem = Node; FreeNextAddress = FreeMem.offset + FreeMem.Size; // 解放メモリが空き領域より後ろにある場合 if (Mem.offset > FreeNextAddress) { // 空き領域の後に解放メモリを空き領域として追加 m_FreeMem.AddAfter(Node, Mem); return true; } // 解放メモリの次のアドレスが空き領域のアドレスの場合 else if (NextAddress == FreeMem) { // 空き領域の前に解放メモリを融合 ChangeAddress(ref FreeMem, new TMemNode(new pointer(FreeMem, -Mem.Size), FreeMem.Size + Mem.Size), FreeMem.Size + Mem.Size); if (Prev != null) { // 前の空き領域のアドレスが解放メモリの次のアドレスの場合 Mem = Prev; if (FreeMem.offset == (Mem.offset + Mem.Size)) { // 空き領域の前に前の空き領域を融合 ChangeAddress(ref FreeMem, new TMemNode(new pointer(FreeMem, -Mem.Size), FreeMem.Size + Mem.Size), FreeMem.Size + Mem.Size); // 前の空き領域を削除 m_FreeMem.Remove(Prev); } } return true; } // 解放メモリのアドレスが空き領域の次のアドレスの場合 else if (Mem.offset == FreeNextAddress) { // 空き領域リストの最後に解放メモリを空き領域として追加 FreeMem.Size += Mem.Size; return true; } // 解放メモリが不正の場合 else if (((Mem > FreeMem) && (Mem.offset < FreeNextAddress)) || ((NextAddress > FreeMem) && (NextAddress.offset < FreeNextAddress))) { return false; } } // 解放メモリのアドレスが、管理領域内の場合 if (Mem >= m_cmpl.addr) { // 空き領域リストの最初に解放メモリを空き領域として追加 m_FreeMem.AddFirst(Mem); return true; } } return false; }
public TMemNodeList() { First = null; Last = null; Count = 0; }
private bool Free(TMemNode Mem) { TMemNode Node; TMemNode FreeMem; pointer NextAddress = ((pointer)Mem) + Mem.Size; int FreeNextAddress; // 解放メモリサイズが空き領域に対してある程度小さい場合 if (Mem.Size < m_cmpl.mplsz / 8) { // 空き領域リストの先頭から検索 TMemNode Next; TMemNode NextFreeMem; // 解放メモリのアドレスが、管理領域の先頭より前の場合 if (Mem < m_cmpl.addr) { return(false); } Next = m_FreeMem.First; while (Next != null) { Node = Next; Next = Node.Next; FreeMem = Node; FreeNextAddress = FreeMem.offset + FreeMem.Size; // 解放メモリが空き領域より前にある場合 if (NextAddress < FreeMem) { // 空き領域の前に解放メモリを空き領域として追加 m_FreeMem.AddBefore(Node, Mem); return(true); } // 解放メモリのアドレスが空き領域の次のアドレスの場合 else if (Mem.offset == FreeNextAddress) { // 空き領域の後ろに解放メモリを融合 FreeMem.Size += Mem.Size; if (Next != null) { // 次の空き領域のアドレスが解放メモリの次のアドレスの場合 NextFreeMem = Next; if (NextAddress == ((pointer)NextFreeMem)) { // 空き領域に次の空き領域を融合 FreeMem.Size += NextFreeMem.Size; // 次の空き領域を削除 m_FreeMem.Remove(Next); } } return(true); } // 空き領域の次のアドレスが解放メモリのアドレスの場合 else if (NextAddress == FreeMem) { // 空き領域の前に解放メモリを融合 ChangeAddress(ref FreeMem, Mem, FreeMem.Size + Mem.Size); return(true); } // 解放メモリが不正の場合 else if (((Mem > FreeMem) && (Mem.offset < FreeNextAddress)) || ((NextAddress > FreeMem) && (NextAddress.offset < FreeNextAddress))) { return(false); } } // 解放メモリのアドレスが、管理領域内の場合 if (NextAddress <= (m_cmpl.addr + m_cmpl.mplsz)) { // 空き領域リストの最後に解放メモリを空き領域として追加 m_FreeMem.AddLast(Mem); return(true); } } // 大きい場合 else { // 空き領域リストの末尾から検索 TMemNode Prev; // 解放メモリのアドレスが、管理領域の末尾より後の場合 if (NextAddress > (m_cmpl.addr + m_cmpl.mplsz)) { return(false); } Prev = m_FreeMem.Last; while (Prev != null) { Node = Prev; Prev = Node.Previous; FreeMem = Node; FreeNextAddress = FreeMem.offset + FreeMem.Size; // 解放メモリが空き領域より後ろにある場合 if (Mem.offset > FreeNextAddress) { // 空き領域の後に解放メモリを空き領域として追加 m_FreeMem.AddAfter(Node, Mem); return(true); } // 解放メモリの次のアドレスが空き領域のアドレスの場合 else if (NextAddress == FreeMem) { // 空き領域の前に解放メモリを融合 ChangeAddress(ref FreeMem, new TMemNode(new pointer(FreeMem, -Mem.Size), FreeMem.Size + Mem.Size), FreeMem.Size + Mem.Size); if (Prev != null) { // 前の空き領域のアドレスが解放メモリの次のアドレスの場合 Mem = Prev; if (FreeMem.offset == (Mem.offset + Mem.Size)) { // 空き領域の前に前の空き領域を融合 ChangeAddress(ref FreeMem, new TMemNode(new pointer(FreeMem, -Mem.Size), FreeMem.Size + Mem.Size), FreeMem.Size + Mem.Size); // 前の空き領域を削除 m_FreeMem.Remove(Prev); } } return(true); } // 解放メモリのアドレスが空き領域の次のアドレスの場合 else if (Mem.offset == FreeNextAddress) { // 空き領域リストの最後に解放メモリを空き領域として追加 FreeMem.Size += Mem.Size; return(true); } // 解放メモリが不正の場合 else if (((Mem > FreeMem) && (Mem.offset < FreeNextAddress)) || ((NextAddress > FreeMem) && (NextAddress.offset < FreeNextAddress))) { return(false); } } // 解放メモリのアドレスが、管理領域内の場合 if (Mem >= m_cmpl.addr) { // 空き領域リストの最初に解放メモリを空き領域として追加 m_FreeMem.AddFirst(Mem); return(true); } } return(false); }
private TMemNode Allocate(TMemNode Node, int Size) { TMemNode FreeMem = Node; TMemNode Result; // 取得サイズが空き領域に対してある程度小さい場合 if (Size < FreeMem.Size / 8) { // 空き領域の先頭から割り当て Result = FreeMem; ChangeAddress(ref FreeMem, new TMemNode(new pointer(FreeMem, Size), FreeMem.Size - Size), FreeMem.Size - Size); Result = new TMemNode(Result, Size); } // 大きい場合 else { // 空き領域の末尾から割り当て FreeMem.Size = FreeMem.Size - Size; Result = new TMemNode(new pointer(FreeMem, FreeMem.Size), Size); } return Result; }