Exemple #1
0
        public KMemoryBlock Allocate( string name, KAllocType type, uint address, uint size )
        {
            KMemoryBlock newBlock = null;

            // Round size up to the next word
            //if( ( size & 0x3 ) != 0 )
            //    size += 4 - ( size & 0x3 );

            if( ( type == KAllocType.LowAligned ) ||
                ( type == KAllocType.HighAligned ) )
            {
                // TODO: align at 'address' (like 4096, etc)
                address = 0;

                // Other logic is the same
                if( type == KAllocType.LowAligned )
                    type = KAllocType.Low;
                else if( type == KAllocType.HighAligned )
                    type = KAllocType.High;
            }

            // Quick check to see if we have the space free
            Debug.Assert( FreeSize >= size );
            if( FreeSize < size )
                return null;

            switch( type )
            {
                case KAllocType.Specific:
                    {
                        Debug.Assert( address != 0 );
                        LinkedListEntry<KMemoryBlock> e = FreeList.HeadEntry;
                        while( e != null )
                        {
                            if( ( address >= e.Value.Address ) &&
                                ( address < e.Value.UpperBound ) )
                            {
                                newBlock = this.SplitBlock( e.Value, address, size );
                                break;
                            }
                            e = e.Next;
                        }
                    }
                    break;
                case KAllocType.Low:
                    {
                        KMemoryBlock targetBlock = null;
                        uint maxContig = 0;
                        if( address != 0 )
                        {
                            // Specified lower limit, find the first block that fits
                            LinkedListEntry<KMemoryBlock> e = FreeList.HeadEntry;
                            while( e != null )
                            {
                                if( ( address >= e.Value.Address ) &&
                                    ( address < e.Value.UpperBound ) )
                                {
                                    targetBlock = e.Value;
                                    break;
                                }
                                maxContig = Math.Max( maxContig, e.Value.Size );
                                e = e.Next;
                            }
                        }
                        else
                        {
                            // No lower limit - pick first free block that fits
                            LinkedListEntry<KMemoryBlock> e = FreeList.HeadEntry;
                            while( e != null )
                            {
                                if( e.Value.Size >= size )
                                {
                                    targetBlock = e.Value;
                                    break;
                                }
                                maxContig = Math.Max( maxContig, e.Value.Size );
                                e = e.Next;
                            }
                        }
                        Debug.Assert( targetBlock != null );
                        if( targetBlock == null )
                        {
                            // Try again with a smaller size
                            Log.WriteLine( Verbosity.Critical, Feature.Bios, "KPartition::Allocate could not find enough space" );
                            //return this.Allocate( KAllocType.Maximum, 0, maxContig );
                            return null;
                        }
                        Debug.Assert( targetBlock.Size >= size );
                        if( targetBlock.Size < size )
                            return null;
                        newBlock = this.SplitBlock( targetBlock,
                            ( address != 0 ) ? address : targetBlock.Address,
                            size );
                    }
                    break;
                case KAllocType.High:
                    {
                        Debug.Assert( address == 0 );
                        KMemoryBlock targetBlock = null;
                        LinkedListEntry<KMemoryBlock> e = FreeList.TailEntry;
                        while( e != null )
                        {
                            if( e.Value.Size >= size )
                            {
                                targetBlock = e.Value;
                                break;
                            }
                            e = e.Previous;
                        }
                        Debug.Assert( targetBlock != null );
                        if( targetBlock == null )
                        {
                            // Try again with a smaller size
                            Log.WriteLine( Verbosity.Critical, Feature.Bios, "KPartition::Allocate could not find enough space" );
                            //return this.Allocate( KAllocType.Maximum, 0, maxContig );
                            return null;
                        }
                        Debug.Assert( ( int )targetBlock.UpperBound - ( int )size >= 0 );
                        newBlock = this.SplitBlock( targetBlock, targetBlock.UpperBound - size, size );
                    }
                    break;
            }

            if( newBlock != null )
            {
                newBlock.Name = name;
                newBlock.IsFree = false;
                FreeSize -= size;
            }
            this.Kernel.PrintMemoryInfo();
            return newBlock;
        }
Exemple #2
0
        public KMemoryBlock Allocate(string name, KAllocType type, uint address, uint size)
        {
            KMemoryBlock newBlock = null;

            // Round size up to the next word
            //if( ( size & 0x3 ) != 0 )
            //    size += 4 - ( size & 0x3 );

            if ((type == KAllocType.LowAligned) ||
                (type == KAllocType.HighAligned))
            {
                // TODO: align at 'address' (like 4096, etc)
                address = 0;

                // Other logic is the same
                if (type == KAllocType.LowAligned)
                {
                    type = KAllocType.Low;
                }
                else if (type == KAllocType.HighAligned)
                {
                    type = KAllocType.High;
                }
            }

            // Quick check to see if we have the space free
            Debug.Assert(FreeSize >= size);
            if (FreeSize < size)
            {
                return(null);
            }

            switch (type)
            {
            case KAllocType.Specific:
            {
                Debug.Assert(address != 0);
                LinkedListEntry <KMemoryBlock> e = FreeList.HeadEntry;
                while (e != null)
                {
                    if ((address >= e.Value.Address) &&
                        (address < e.Value.UpperBound))
                    {
                        newBlock = this.SplitBlock(e.Value, address, size);
                        break;
                    }
                    e = e.Next;
                }
            }
            break;

            case KAllocType.Low:
            {
                KMemoryBlock targetBlock = null;
                uint         maxContig   = 0;
                if (address != 0)
                {
                    // Specified lower limit, find the first block that fits
                    LinkedListEntry <KMemoryBlock> e = FreeList.HeadEntry;
                    while (e != null)
                    {
                        if ((address >= e.Value.Address) &&
                            (address < e.Value.UpperBound))
                        {
                            targetBlock = e.Value;
                            break;
                        }
                        maxContig = Math.Max(maxContig, e.Value.Size);
                        e         = e.Next;
                    }
                }
                else
                {
                    // No lower limit - pick first free block that fits
                    LinkedListEntry <KMemoryBlock> e = FreeList.HeadEntry;
                    while (e != null)
                    {
                        if (e.Value.Size >= size)
                        {
                            targetBlock = e.Value;
                            break;
                        }
                        maxContig = Math.Max(maxContig, e.Value.Size);
                        e         = e.Next;
                    }
                }
                Debug.Assert(targetBlock != null);
                if (targetBlock == null)
                {
                    // Try again with a smaller size
                    Log.WriteLine(Verbosity.Critical, Feature.Bios, "KPartition::Allocate could not find enough space");
                    //return this.Allocate( KAllocType.Maximum, 0, maxContig );
                    return(null);
                }
                Debug.Assert(targetBlock.Size >= size);
                if (targetBlock.Size < size)
                {
                    return(null);
                }
                newBlock = this.SplitBlock(targetBlock,
                                           (address != 0) ? address : targetBlock.Address,
                                           size);
            }
            break;

            case KAllocType.High:
            {
                Debug.Assert(address == 0);
                KMemoryBlock targetBlock         = null;
                LinkedListEntry <KMemoryBlock> e = FreeList.TailEntry;
                while (e != null)
                {
                    if (e.Value.Size >= size)
                    {
                        targetBlock = e.Value;
                        break;
                    }
                    e = e.Previous;
                }
                Debug.Assert(targetBlock != null);
                if (targetBlock == null)
                {
                    // Try again with a smaller size
                    Log.WriteLine(Verbosity.Critical, Feature.Bios, "KPartition::Allocate could not find enough space");
                    //return this.Allocate( KAllocType.Maximum, 0, maxContig );
                    return(null);
                }
                Debug.Assert(( int )targetBlock.UpperBound - ( int )size >= 0);
                newBlock = this.SplitBlock(targetBlock, targetBlock.UpperBound - size, size);
            }
            break;
            }

            if (newBlock != null)
            {
                newBlock.Name   = name;
                newBlock.IsFree = false;
                FreeSize       -= size;
            }
            this.Kernel.PrintMemoryInfo();
            return(newBlock);
        }