Ejemplo n.º 1
0
        /// <summary>
        /// Allocate a block of memory based upon a best fit policy.
        /// </summary>
        /// <param name="iBlockSizeRequest"></param>
        /// <returns></returns>
        public MemoryBlock Allocate(int iBlockSizeRequest)
        {
            try
            {
                IEnumerable <KeyValuePair <int, List <int> > > availableMemoryBlocks =
                    from entry in MemoryPool
                    where (entry.Key) >= iBlockSizeRequest
                    orderby entry.Key ascending
                    select entry;
                if (0 == availableMemoryBlocks.Count())
                {
                    return(new MemoryBlock());
                }
                KeyValuePair <int, List <int> > smallestBlocks = availableMemoryBlocks.First();
                int iBlockSize    = smallestBlocks.Key;
                int iBlockAddress = smallestBlocks.Value.First();
                smallestBlocks.Value.RemoveAt(0);

                if (0 == smallestBlocks.Value.Count())
                {
                    MemoryPool.Remove(iBlockSize);
                }

                if (iBlockSize > iBlockSizeRequest)
                {
                    int iBlockRemainderSize    = iBlockSize - iBlockSizeRequest;
                    int iBlockRemainderAddress = iBlockAddress + iBlockSizeRequest;
                    if (MemoryPool.ContainsKey(iBlockRemainderSize))
                    {
                        Debug.Assert(!MemoryPool[iBlockRemainderSize].Contains(iBlockRemainderAddress));
                        MemoryPool[iBlockRemainderSize].Add(iBlockRemainderAddress);
                    }
                    else
                    {
                        MemoryPool.Add(iBlockRemainderSize, new List <int>()
                        {
                            iBlockRemainderAddress
                        });
                    }
                }
                return(new MemoryBlock()
                {
                    BlockAddress = iBlockAddress, BlockSize = iBlockSizeRequest
                });
            }
            catch (Exception)
            {
                throw;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Free memory back into memory buffer.
        /// </summary>
        /// <param name="m"></param>
        public void Free(MemoryBlock m)
        {
            if (null == m || m.IsNull())
            {
                return;
            }
            try
            {
                int iBlockAddressStart = m.BlockAddress;
                int iBlockAddressEnd   = m.BlockAddress + m.BlockSize;
                int iMergeBlockSize    = m.BlockSize;
                int iMergeBlockAddress = m.BlockAddress;
                // If Block Address is already available, then ignore
                foreach (KeyValuePair <int, List <int> > kvp in MemoryPool)
                {
                    if (kvp.Value.Contains(m.BlockAddress))
                    {
                        return;
                    }
                }
                // Merge with existing block with start of address
                bool fMergeStart             = false;
                int  iMergeStartBlockSize    = 0;
                int  iMergeStartBlockAddress = 0;
                foreach (KeyValuePair <int, List <int> > kvp in MemoryPool)
                {
                    int iBlockSize = kvp.Key;
                    foreach (int iBlockAddress in kvp.Value)
                    {
                        if (iBlockAddress > iBlockAddressStart)
                        {
                            continue;
                        }
                        if (iBlockSize + iBlockAddress == iBlockAddressStart)
                        {
                            fMergeStart             = true;
                            iMergeStartBlockSize    = iBlockSize;
                            iMergeStartBlockAddress = iBlockAddress;
                            MemoryPool[iBlockSize].Remove(iBlockAddress);
                            if (0 == MemoryPool[iBlockSize].Count())
                            {
                                MemoryPool.Remove(iBlockSize);
                            }
                            break;
                        }
                    }
                    if (fMergeStart)
                    {
                        break;
                    }
                }

                // Merge existing block with the end of the block
                if (fMergeStart)
                {
                    iMergeBlockSize   += iMergeStartBlockSize;
                    iMergeBlockAddress = iMergeStartBlockAddress;
                }

                bool fMergeEnd             = false;
                int  iMergeEndBlockSize    = 0;
                int  iMergeEndBlockAddress = 0;
                IEnumerable <KeyValuePair <int, List <int> > > availableMemoryBlocksWithAddressEnd =
                    from entry in MemoryPool
                    where (entry.Value.Contains(iBlockAddressEnd))
                    select entry;

                if (0 < availableMemoryBlocksWithAddressEnd.Count())
                {
                    fMergeEnd = true;
                    KeyValuePair <int, List <int> > kvp = availableMemoryBlocksWithAddressEnd.First();
                    iMergeEndBlockSize    = kvp.Key;
                    iMergeEndBlockAddress = iBlockAddressEnd;
                    Debug.Assert(MemoryPool[iMergeEndBlockSize].Contains(iMergeEndBlockAddress));
                    MemoryPool[iMergeEndBlockSize].Remove(iMergeEndBlockAddress);
                    if (0 == MemoryPool[iMergeEndBlockSize].Count)
                    {
                        MemoryPool.Remove(iMergeEndBlockSize);
                    }
                }

                if (fMergeEnd)
                {
                    iMergeBlockSize += iMergeEndBlockSize;
                }

                if (MemoryPool.Keys.Contains(iMergeBlockSize))
                {
                    MemoryPool[iMergeBlockSize].Add(iMergeBlockAddress);
                }
                else
                {
                    MemoryPool.Add(iMergeBlockSize, new List <int>()
                    {
                        iMergeBlockAddress
                    });
                }
            }
            catch (Exception)
            {
                throw;
            }
        }