Пример #1
0
        private static uint internalAllocation(uint size, bool allign)
        {
            totalAllocations++;
            tryAgain :;
            uint returnable = 0;

            if (Settings.HeapUseBasic || entryCount == 0)
            {
                if (heapPointer == 0)
                {
                    heapPointer = Utils.allign4K(Multiboot.GetEndOfKernel()) + 4096;
                }
                if (allign)
                {
                    heapPointer = Utils.allign4K(heapPointer) + 4096;
                }
                uint tmp = heapPointer;
                heapPointer += size;
                returnable   = tmp;
                goto allocationEnd;
            }
            mutex.Lock();
            if (currentEntry >= entryCount)
            {
                currentEntry = 0;
            }
            var entry = directory->GetEntry(currentEntry);

            if (entry->used)
            {
                currentEntry++;
                goto tryAgain;
            }
            if (!allign && size < 4096)
            {
                if (entry->size <= size && entry->location != 0)
                {
                    entry->used = true;
                    returnable  = entry->location;
                    goto allocationEnd;
                }
                if (size > pageSpace)
                {
                    pageSpace   = 4096;
                    heapPointer = PageManager.GetFreePage();
                    if (heapPointer == 0)
                    {
                        // need to to a GC scan and free some pages
                        Console.WriteLine("RAN OUT OF RAM");
                        ACPI.Shutdown();
                        while (true)
                        {
                        }
                    }
                }
                pageSpace      -= size;
                entry->size     = size;
                entry->location = heapPointer;
                heapPointer    += size;
                entry->used     = true;
                returnable      = entry->location;
                goto allocationEnd;
            }
            else
            {
                int num       = (int)(size / 4096);
                int remainder = (int)(size % 4096);
                if (remainder > 0)
                {
                    num++;
                }
                entry->used     = true;
                entry->location = PageManager.GetFreePage(num);
                entry->size     = (uint)num * 4096;
                returnable      = entry->location;
                goto allocationEnd;
            }
            allocationEnd :;
            Utils.memset((byte *)returnable, 0, size);
            mutex.Unlock();
            return(returnable);
        }