Exemplo n.º 1
0
        public VSFreeSpaceManager(VSpace _sp)
        {
            Space = _sp;
            vm    = Space.VM;

            long hdr_address = Space.GetFirstAddress(DEFS.POOL_FREE_SPACE);

            if (hdr_address == 0)
            { // Initialization
                // 1. Create H-block (header)
                H_Object = new VSAllocation(vm, DEFS.FBQE_HEADER_ADDRESS, DEFS.FBQE_HEADER_LENGTH_FULL, 0);
                H_Object.Write(0, DEFS.FBQE_HEADER_SIGNATURE);
                this.MAX     = DEFS.FBQE_ALLOCATION_NUMBER;                                        // Max number of FBQE
                this.FREE    = MAX;
                this.FIRST   = -1;
                this.LAST    = -1;
                this.FIRST_Q = 0;
                this.LAST_Q  = FREE - 1;

                // 2. Save H-block address (1st object)
                Space.SetFirstAddress(DEFS.POOL_FREE_SPACE, H_Object.DescriptorAddress);      // 1st object

                // 3. Create 1st FBQE block
                F_Object = new VSAllocation(vm, H_Object.DescriptorAddress + H_Object.FullLength, (DEFS.FBQE_ALLOCATION_LENGTH + DEFS.BaseDescriptorLength), 0);

                // 4. Set initial size
                F_Object.SetSize(DEFS.FBQE_ALLOCATION_LENGTH);
                buffer = new byte[F_Object.Size];                   // Create buffer

                // 5. Set references
                F_Object.PREV = H_Object.DescriptorAddress;
                H_Object.NEXT = F_Object.DescriptorAddress;                                     // Address of the 1st block F-block


                // 6. Save F-block address (last object)
                Space.SetLastAddress(DEFS.POOL_FREE_SPACE, F_Object.DescriptorAddress);         //last object



                // 1.3 Initiate Free queue
                for (int i = 0; i < FREE; i++)
                {
                    CreateFBQE(i);
                }

                BuildBTrees();

                // 1.4 Create initial FBQE
                long fa = F_Object.DescriptorAddress + F_Object.FullLength;                     // 1st free address

                AddFBQE(fa, (Space.vm.Size - fa), -1, -1);                                      // Create 1st FBQE
            }
            else
            {
                H_Object = Space.GetAllocationByDescriptor(hdr_address);
                F_Object = Space.GetAllocationByDescriptor(H_Object.NEXT);

                byte[] b = H_Object.ReadBytes(0, FBQE_HEADER_LENGTH);


                this.v_MAX     = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, MAX_POS, MAX_LEN));
                this.v_FREE    = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, FREE_POS, FREE_LEN));
                this.v_FIRST   = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, FIRST_POS, FIRST_LEN));
                this.v_LAST    = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, LAST_POS, LAST_LEN));
                this.v_FIRST_Q = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, FIRST_Q_POS, FIRST_Q_LEN));
                this.v_LAST_Q  = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, LAST_Q_POS, LAST_Q_LEN));

                buffer = F_Object.ReadBytes(0, F_Object.Size);                   // Read buffer
                BuildBTrees();
            }
        }
Exemplo n.º 2
0
        /************************************************************************************/
        /************************   Memory management (system methods)***********************/
        /************************************************************************************/


        /// <summary>
        /// Allocate space (system method)
        /// </summary>
        /// <param name="size">Allocation size</param>
        /// <param name="pool">Allocation pool. 0 if base_address != 0</param>
        /// <param name="generateID">True id ID is required. false if base_address != 0</param>
        /// <param name="base_address"> 1st allocated address (extend)</param>
        /// <returns>
        /// 0 - address
        /// 1 - ID (or 0)
        /// </returns>
        internal VSAllocation AllocateSpaceSegment(long size, short pool, bool generateID = true, VSAllocation base_alloc = null)
        {
#if (DEBUG)
            __TIMER.START("alloc:main");
#endif

            if ((base_alloc != null) & ((pool != 0) | (generateID == true)))
            {
                throw new VSException(DEFS.E0020_INVALID_EXTENSION_PARAMETERS_ERROR_CODE);
            }

            //VSFreeSpaceManager.FBQE f;
            long alloc_addr  = 0;
            long length_desc = (base_alloc == null)? DEFS.BaseDescriptorLength: DEFS.ExpansionDescriptorLength;       // Descriptor length


            // Calculate allocation size)
            long length = size / DEFS.MIN_SPACE_ALLOCATION_CHUNK;

            if (length == 0)
            {
                length++;
            }
            else if ((length * DEFS.MIN_SPACE_ALLOCATION_CHUNK) < size)
            {
                length++;
            }

            long length_use = (length * DEFS.MIN_SPACE_ALLOCATION_CHUNK);

            length = length_use + length_desc;

            // Acquire free space location
            alloc_addr = FreeSpaceMgr.AcquireSpace(length);

            while (alloc_addr == 0)
            {
                if (vm.Extend() != 0)
                {
                    throw new VSException(DEFS.E0013_SPACE_NOT_AVAILABLE_CODE, "Requested size: " + length.ToString());
                }
                else
                {
                    this.VerifySpaceChanges();         //Process new if space is successfully extended
                }
                alloc_addr = FreeSpaceMgr.AcquireSpace(length);
            }


            short new_pool = pool;

            // If base_address != 0 - take pool# from the root descriptor
            if (base_alloc != null)
            {
                new_pool = base_alloc.Pool;
            }

            // Create allocated space descriptor
            VSAllocation new_obj = new VSAllocation(vm, alloc_addr, length, new_pool);

            long last_obj = GetLastAddress(new_pool);

            VSAllocation prev_obj;
            if (base_alloc == null)
            { // Initial allocation
#if (DEBUG)
                __TIMER.START("alloc:new_alloc");
#endif
#if (DEBUG)
                __TIMER.START("alloc:gen_id");
#endif
                if (generateID)
                {
                    new_obj.Id = key_manager.Add(new_obj);              // Generate ID if required
                }
#if (DEBUG)
                __TIMER.END("alloc:gen_id");
#endif

                if (last_obj == 0)
                { // First allocation for pool
                    SetFirstAddress(new_pool, alloc_addr);
                    SetLastAddress(new_pool, alloc_addr);
                }
                else
                {
                    prev_obj      = GetAllocationByDescriptor(last_obj);
                    prev_obj.NEXT = new_obj.DescriptorAddress;
                    new_obj.PREV  = prev_obj.DescriptorAddress;
                    SetLastAddress(new_pool, new_obj.DescriptorAddress);        // New Last
                }
#if (DEBUG)
                __TIMER.END("alloc:new_alloc");
#endif
            }
            else
            { //Extend
#if (DEBUG)
                __TIMER.START("alloc:extend_obj");
#endif

                prev_obj = base_alloc;
                if (base_alloc.Chunk == 0)
                {
                    base_alloc.Chunk = 1;
                    new_obj.Chunk    = -2;
                }
                else
                {
                    prev_obj = GetAllocationByDescriptor(base_alloc.LAST);
                    short ch = (short)(prev_obj.Chunk * -1);
                    if (ch == DEFS.MAX_SPACE_ALLOCATION_CHUNKS)
                    {
                        throw new VSException(DEFS.E0021_MAX_ALLOCATION_CHUNKS_REACHED_CODE, "- " + DEFS.MAX_SPACE_ALLOCATION_CHUNKS.ToString());
                    }
                    prev_obj.Chunk = ch;
                    new_obj.Chunk  = (short)((ch + 1) * -1);
                }

                base_alloc.LAST = new_obj.DescriptorAddress;                      // New pointer to last

                if (prev_obj.NEXT == 0)
                {
                    prev_obj.NEXT = new_obj.DescriptorAddress;
                    new_obj.PREV  = prev_obj.DescriptorAddress;
                    SetLastAddress(new_pool, new_obj.DescriptorAddress);        // New last
                }
                else
                {
                    VSAllocation next_obj = GetAllocationByDescriptor(prev_obj.NEXT);
                    prev_obj.NEXT = new_obj.DescriptorAddress;
                    new_obj.NEXT  = next_obj.DescriptorAddress;
                    new_obj.PREV  = prev_obj.DescriptorAddress;
                    next_obj.PREV = new_obj.DescriptorAddress;
                }
#if (DEBUG)
                __TIMER.END("alloc:extend_obj");
#endif
            }

            if (base_alloc == null)
            {
                new_obj.SetSize(length_use);
            }
            else
            {
                base_alloc.SetSize(base_alloc.Size + length_use);
            }
#if (DEBUG)
            __TIMER.END("alloc:main");
#endif

            return(new_obj);
        }