Esempio n. 1
0
        // print buddy system status
        //void dump_print(struct mem_zone * zone);
        //void dump_print_dot(struct mem_zone * zone);

        //---###---

        public static void buddy_system_init(mem_zone *zone,
                                             page *start_page,
                                             uint start_addr,
                                             uint page_num)
        {
            uint       i;
            page *     page = null;
            free_area *area = null;

            // init memory zone
            zone->page_num   = page_num;
            zone->page_size  = BUDDY_PAGE_SIZE;
            zone->first_page = start_page;
            zone->start_addr = start_addr;
            zone->end_addr   = start_addr + (page_num * BUDDY_PAGE_SIZE);
            // TODO: init zone->lock
            // init each area
            for (i = 0; i < BUDDY_MAX_ORDER; i++)
            {
                area = zone->free_area + i;
                INIT_LIST_HEAD(&area->free_list);
                area->nr_free = 0;
            }
            memset((byte *)start_page, 0, page_num * (uint)sizeof(page));
            // init and free each page
            for (i = 0; i < page_num; i++)
            {
                page = zone->first_page + i;
                INIT_LIST_HEAD(&page->lru);
                // TODO: init page->lock
                buddy_free_pages(zone, page);
            }
        }
Esempio n. 2
0
        static page *expand(zone *zone, page *page, int low, int high, free_area *area)
        {
            uint size = (uint)1 << (byte)high;

            while (high > low)
            {
                area--;
                high--;
                size >>= 1;
                //BUG_ON(bad_range(zone, &page[size]));
                list_add(&page[size].Lru, &area->Free_list);
                area->Nr_free++;
                set_page_order(&page[size], high);
            }
            return(page);
        }
Esempio n. 3
0
        /// <summary>
        /// Split the combined page to get the page of the desired size
        /// </summary>
        static void expand(mem_zone *zone, page *page,
                           byte low_order, byte high_order,
                           free_area *area)
        {
            uint size = (1U << high_order);

            while (high_order > low_order)
            {
                area--;
                high_order--;
                size >>= 1;
                list_add(&page[size].lru, &area->free_list);
                area->nr_free++;
                // set page order
                set_page_order_buddy(&page[size], high_order);
            }
        }
Esempio n. 4
0
        static page *__alloc_page(byte order,
                                  mem_zone *zone)
        {
            page *     page          = null;
            free_area *area          = null;
            byte       current_order = 0;

            for (current_order = order;
                 current_order < BUDDY_MAX_ORDER; current_order++)
            {
                area = zone->free_area + current_order;
                if (list_empty(&area->free_list))
                {
                    continue;
                }
                // remove closest size page
                //page = list_entry(area->free_list.next, struct page, lru);
                page = (page *)&((page *)area->free_list.next)->lru;

                list_del(&page->lru);
                rmv_page_order_buddy(page);
                area->nr_free--;
                // expand to lower order
                expand(zone, page, order, current_order, area);
                // compound page
                if (order > 0)
                {
                    prepare_compound_pages(page, order);
                }
                else // single page
                {
                    page->order = 0;
                }
                return(page);
            }
            return(null);
        }