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); }
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; } }