Ejemplo n.º 1
0
        /// <returns>
        /// Address of node with unallocated block of sufficient size to hold
        /// given/wanted amount of bytes.
        ///
        /// 0, if no such node was found.
        /// </returns>
        public static ushort GetAllocNodeAddr(ushort wantedLen)
        {
            Debug.Assert(wantedLen > 0);

            ushort retVal         = 0,
                   firstBlockAddr = NodeMem.GetFirstBlockAddr(),
                   blockLen       = 0;
            Node n = null;

            for (ushort addr = NodeMem._firstNodeAddr;
                 addr != 0;
                 addr = n.NextNodeAddr)
            {
                n = Node.Load(addr);

                if (n.IsAllocated != 0)
                {
                    continue; // Node's block is already allocated.
                }

                if (n.BlockLen < wantedLen)
                {
                    continue; // Would not fit in node's block.
                }

                if (n.BlockAddr == firstBlockAddr)
                {
                    if (retVal == 0)
                    {
                        retVal   = addr; // No better candidate found, yet.
                        blockLen = n.BlockLen;
                    }
                    continue;
                }

                if (n.BlockLen == wantedLen)
                {
                    retVal = addr;
                    break; // Fits perfectly. Found!
                }

                if (retVal == 0)
                {
                    retVal   = addr;
                    blockLen = n.BlockLen;
                    continue; // No better candidate found, yet.
                }

                if (blockLen > n.BlockLen)
                {
                    // Would fit better than current best candidate.

                    retVal   = addr;
                    blockLen = n.BlockLen;
                }
            }
            return(retVal);
        }
Ejemplo n.º 2
0
        private static void Free(ushort blockAddr)
        {
            ushort nodeAddr = 0;
            Node   cur      = null;

            if (blockAddr == 0)
            {
                //Debug.Assert(false);
                return; // Nothing to do.
            }

            nodeAddr = NodeMem.GetBlockNodeAddr(blockAddr);
            if (nodeAddr == 0)
            {
                Debug.Assert(false);
                return; // No block at given (start) address is allocated.
            }

            cur = Node.Load(nodeAddr);

            if (cur.IsAllocated == 0)
            {
                Debug.Assert(false);
                return; // Already deallocated.
            }

            cur.IsAllocated = 0;
            Node.Store(nodeAddr, cur);

#if DEBUG
            Mem.Clear(cur.BlockAddr, cur.BlockLen, 0xCD);
#endif //DEBUG

            if (cur.NextNodeAddr != 0)
            {
                NodeMem.MergeUnallocatedWithNextIfPossible(nodeAddr);
            }
            if (cur.LastNodeAddr != 0 &&
                Node.Load(cur.LastNodeAddr).IsAllocated == 0)
            {
                NodeMem.MergeUnallocatedWithNextIfPossible(cur.LastNodeAddr);
            }

            NodeMem.LimitFreeNodes();
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            NodeMem.Init();

            var all = Alloc(Mem.HeapLen - 2 * Node.NodeLen);

            Mem.Clear(all, Mem.HeapLen - 2 * Node.NodeLen, 0xBC);

            Mem.Print();
            Console.WriteLine("***");

            Free(all);
            all = 0;

            var a = Alloc(10);

            Mem.Clear(a, 10, 170);

            var b = Alloc(5);

            Mem.Clear(b, 5, 187);

            var c = Alloc(7);

            Mem.Clear(c, 7, 204);

            Mem.Print();
            Console.WriteLine("-");

            Free(c);

            Mem.Print();
            Console.WriteLine("-");

            Free(b);

            Mem.Print();
            Console.WriteLine("-");

            Free(a);

            Mem.Print();
        }
Ejemplo n.º 4
0
        private static ushort Alloc(ushort wantedLen)
        {
            ushort newNodeAddr = 0,
                   nodeAddr    = 0;
            Node n             = null,
                 newNode       = null;

            if (wantedLen == 0)
            {
                return(0);
            }

            // Make sure that there is a node space available, first
            // (and maybe frees space from first node, which must
            // be done BEFORE first node may gets selected as
            // "alloc" node):
            //
            if (!NodeMem.TryToReserveNodeSpace())
            {
                return(0); // No more space for another node available.
            }

            nodeAddr = NodeMem.GetAllocNodeAddr(wantedLen);
            if (nodeAddr == 0)
            {
                return(0);
            }

            n = Node.Load(nodeAddr);

            Debug.Assert(n.IsAllocated == 0);

            if (n.BlockLen == wantedLen)
            {
                n.IsAllocated = 1;
                Node.Store(nodeAddr, n);
                return(n.BlockAddr);
            }

            newNode              = new Node();
            newNode.BlockLen     = wantedLen;
            newNode.IsAllocated  = 1;
            newNode.LastNodeAddr = nodeAddr;
            newNode.NextNodeAddr = n.NextNodeAddr;
            newNode.BlockAddr    = (ushort)(n.BlockAddr + n.BlockLen - wantedLen);

            newNodeAddr = NodeMem.Store(newNode);
            n           = null;
            if (newNodeAddr == 0)
            {
                return(0);
            }
            n = Node.Load(nodeAddr);

            Debug.Assert(n.BlockLen > newNode.BlockLen);

            n.BlockLen    -= newNode.BlockLen;
            n.NextNodeAddr = newNodeAddr;
            Node.Store(nodeAddr, n);

            if (newNode.NextNodeAddr != 0)
            {
                Node nextNode = Node.Load(newNode.NextNodeAddr);

                nextNode.LastNodeAddr = newNodeAddr;

                Node.Store(newNode.NextNodeAddr, nextNode);
            }

            return(newNode.BlockAddr);
        }