Exemplo n.º 1
0
        private void InsertBlock(
            long BasePosition,
            long PagesCount,
            MemoryState State,
            MemoryPermission Permission = MemoryPermission.None,
            MemoryAttribute Attribute   = MemoryAttribute.None)
        {
            //Inserts new block at the list, replacing and spliting
            //existing blocks as needed.
            KMemoryBlock Block = new KMemoryBlock(BasePosition, PagesCount, State, Permission, Attribute);

            ulong Start = (ulong)BasePosition;
            ulong End   = (ulong)PagesCount * PageSize + Start;

            LinkedListNode <KMemoryBlock> NewNode = null;

            LinkedListNode <KMemoryBlock> Node = Blocks.First;

            while (Node != null)
            {
                KMemoryBlock CurrBlock = Node.Value;

                LinkedListNode <KMemoryBlock> NextNode = Node.Next;

                ulong CurrStart = (ulong)CurrBlock.BasePosition;
                ulong CurrEnd   = (ulong)CurrBlock.PagesCount * PageSize + CurrStart;

                if (Start < CurrEnd && CurrStart < End)
                {
                    if (Start >= CurrStart && End <= CurrEnd)
                    {
                        Block.Attribute |= CurrBlock.Attribute & MemoryAttribute.IpcAndDeviceMapped;
                    }

                    if (Start > CurrStart && End < CurrEnd)
                    {
                        CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize);

                        long NextPagesCount = (long)((CurrEnd - End) / PageSize);

                        NewNode = Blocks.AddAfter(Node, Block);

                        Blocks.AddAfter(NewNode, new KMemoryBlock(
                                            (long)End,
                                            NextPagesCount,
                                            CurrBlock.State,
                                            CurrBlock.Permission,
                                            CurrBlock.Attribute));

                        break;
                    }
                    else if (Start <= CurrStart && End < CurrEnd)
                    {
                        CurrBlock.BasePosition = (long)End;

                        CurrBlock.PagesCount = (long)((CurrEnd - End) / PageSize);

                        if (NewNode == null)
                        {
                            NewNode = Blocks.AddBefore(Node, Block);
                        }
                    }
                    else if (Start > CurrStart && End >= CurrEnd)
                    {
                        CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize);

                        if (NewNode == null)
                        {
                            NewNode = Blocks.AddAfter(Node, Block);
                        }
                    }
                    else
                    {
                        if (NewNode == null)
                        {
                            NewNode = Blocks.AddBefore(Node, Block);
                        }

                        Blocks.Remove(Node);
                    }
                }

                Node = NextNode;
            }

            if (NewNode == null)
            {
                NewNode = Blocks.AddFirst(Block);
            }

            MergeEqualStateNeighbours(NewNode);
        }
Exemplo n.º 2
0
        private void InsertBlock(
            long BasePosition,
            long PagesCount,
            MemoryState OldState,
            MemoryPermission OldPermission,
            MemoryAttribute OldAttribute,
            MemoryState NewState,
            MemoryPermission NewPermission,
            MemoryAttribute NewAttribute)
        {
            //Insert new block on the list only on areas where the state
            //of the block matches the state specified on the Old* state
            //arguments, otherwise leave it as is.
            OldAttribute |= MemoryAttribute.IpcAndDeviceMapped;

            ulong Start = (ulong)BasePosition;
            ulong End   = (ulong)PagesCount * PageSize + Start;

            LinkedListNode <KMemoryBlock> Node = Blocks.First;

            while (Node != null)
            {
                LinkedListNode <KMemoryBlock> NewNode  = Node;
                LinkedListNode <KMemoryBlock> NextNode = Node.Next;

                KMemoryBlock CurrBlock = Node.Value;

                ulong CurrStart = (ulong)CurrBlock.BasePosition;
                ulong CurrEnd   = (ulong)CurrBlock.PagesCount * PageSize + CurrStart;

                if (Start < CurrEnd && CurrStart < End)
                {
                    MemoryAttribute CurrBlockAttr = CurrBlock.Attribute | MemoryAttribute.IpcAndDeviceMapped;

                    if (CurrBlock.State != OldState ||
                        CurrBlock.Permission != OldPermission ||
                        CurrBlockAttr != OldAttribute)
                    {
                        Node = NextNode;

                        continue;
                    }

                    if (CurrStart >= Start && CurrEnd <= End)
                    {
                        CurrBlock.State      = NewState;
                        CurrBlock.Permission = NewPermission;
                        CurrBlock.Attribute &= ~MemoryAttribute.IpcAndDeviceMapped;
                        CurrBlock.Attribute |= NewAttribute;
                    }
                    else if (CurrStart >= Start)
                    {
                        CurrBlock.BasePosition = (long)End;

                        CurrBlock.PagesCount = (long)((CurrEnd - End) / PageSize);

                        long NewPagesCount = (long)((End - CurrStart) / PageSize);

                        NewNode = Blocks.AddBefore(Node, new KMemoryBlock(
                                                       (long)CurrStart,
                                                       NewPagesCount,
                                                       NewState,
                                                       NewPermission,
                                                       NewAttribute));
                    }
                    else if (CurrEnd <= End)
                    {
                        CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize);

                        long NewPagesCount = (long)((CurrEnd - Start) / PageSize);

                        NewNode = Blocks.AddAfter(Node, new KMemoryBlock(
                                                      BasePosition,
                                                      NewPagesCount,
                                                      NewState,
                                                      NewPermission,
                                                      NewAttribute));
                    }
                    else
                    {
                        CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize);

                        long NextPagesCount = (long)((CurrEnd - End) / PageSize);

                        NewNode = Blocks.AddAfter(Node, new KMemoryBlock(
                                                      BasePosition,
                                                      PagesCount,
                                                      NewState,
                                                      NewPermission,
                                                      NewAttribute));

                        Blocks.AddAfter(NewNode, new KMemoryBlock(
                                            (long)End,
                                            NextPagesCount,
                                            CurrBlock.State,
                                            CurrBlock.Permission,
                                            CurrBlock.Attribute));

                        NextNode = null;
                    }

                    MergeEqualStateNeighbours(NewNode);
                }

                Node = NextNode;
            }
        }