Esempio n. 1
0
        /// <summary>
        /// Adds blocks and all data.
        /// </summary>
        void AddBlock(object op, ulong address,
                      List <ulong> freeBlocks, List <AllocationBlockInfo> blocksLocked,
                      ref uint count)
        {
            // We could add any.
            AllocationBlockInfo info = ScanBlock(address);

            if ((info.LockingOperation != null && info.LockingOperation != op) ||
                info.FreeBlocks.Count == 0)
            {
                return;
            }

            // We add all we can (max count),
            info.LockingOperation = op;
            blocksLocked.Add(info);

            // We remove those used.
            int c = info.FreeBlocks.Count > (int)count ? (int)count : info.FreeBlocks.Count;

            for (int i = 0; i < c; i++)
            {
                ulong addrToAdd = address + (ulong)info.FreeBlocks[i];
                if (addrToAdd == 103)
                {
                    addrToAdd = 103;
                }
                freeBlocks.Add(addrToAdd);
            }

            // Remove used indices.
            count -= (uint)c;
            info.FreeBlocks.RemoveRange(0, c);
        }
Esempio n. 2
0
        /// <summary>
        /// Scans one allocation block.
        /// </summary>
        /// <param name="address">The allocation block address.</param>
        /// <returns></returns>
        AllocationBlockInfo ScanBlock(ulong address)
        {
            AllocationBlockInfo value;

            if (inspectedFreeBlocks.TryGetValue(address, out value))
            {
                return(value);
            }

            BoolArray array = new BoolArray(provider.Read(BlockType.AllocationBlock, address));

            // We first check for all written (fast).
            if (array.IsAllTrue)
            {
                value = new AllocationBlockInfo(address, new List <uint>());
                inspectedFreeBlocks.Add(address, value);
                return(value);
            }

            List <uint> freeBlocks = new List <uint>();

            // We search through all (optimized search, may optimize even better in future.
            // If this will be a bottle neck, we can fix the array outside and than search
            // through it using ulong* pointer (no need to repeat this every time)).
            for (uint i = 0; i < provider.BlockSize / 8; i++)
            {
                // We chaeck 8-bytes at one for all full.
                if (array.IsULongFull(i))
                {
                    continue;
                }

                // For all free.
                if (array.IsULongFree(i))
                {
                    for (uint j = i * 64; j < (i + 1) * 64; j++)
                    {
                        freeBlocks.Add(j + 1);
                    }
                    continue;
                }

                // We now check by byte.
                for (uint j = i * 64; j < (i + 1) * 64; j++)
                {
                    if (!array[j])
                    {
                        freeBlocks.Add(j + 1);
                    }
                }
            }

            value = new AllocationBlockInfo(address, freeBlocks);
            inspectedFreeBlocks.Add(address, value);
            return(value);
        }
Esempio n. 3
0
        /// <summary>
        /// Returns allocations (not commited). Must return even if there is nothing
        /// to return because operation is still blocking the allocation block.
        /// </summary>
        /// <param name="returned"></param>
        public void ReturnAllocations(object returning, List <ulong> returned)
        {
            lock (syncRoot)
            {
                Console.WriteLine("{0} operation returned {1} : {2} blocks returned.",
                                  returning, returned.Count, Common.ArrayToString <ulong>(returned));
                Console.Out.Flush();

                // We first return blocks.
                for (int i = 0; i < returned.Count;)
                {
                    ulong block = returned[i];

                    // We find the block.
                    uint  offset;
                    ulong allocBlock = BlockHelper.GetAllocationBlock(provider.BlockSize, block, out offset);
                    AllocationBlockInfo blockInfo = inspectedFreeBlocks[allocBlock];

                    // We return the address.
                    blockInfo.FreeBlocks.Add(offset);

                    // We check all further (they are sorted so there is a big chance it is in the same block).
                    i++;
                    for (; i < returned.Count; i++)
                    {
                        block = returned[i];

                        // We exit if not in the same block.
                        if (BlockHelper.GetAllocationBlock(provider.BlockSize, block, out offset) != allocBlock)
                        {
                            break;
                        }
                        blockInfo.FreeBlocks.Add(offset);
                    }

                    // Must be sorted.
                    blockInfo.FreeBlocks.Sort();
                }

                // We free all allocation blocks locks.
                List <AllocationBlockInfo> all = lockingList.Find(
                    delegate(OperationLockData data2) { return(data2.Key == returning); }).Info;
                all.ForEach(delegate(AllocationBlockInfo info) { info.LockingOperation = null; });

                // We remove the operation.
                lockingList.RemoveAll(delegate(OperationLockData data3) { return(data3.Key == returning); });
            }
        }