コード例 #1
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        // 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);
            }
        }
コード例 #2
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        //---

        // The Linux kernel records the order of the combined page in the prev pointer of the second page.
        // This system records the order of the combined page in the page->order field of the first page.

        static byte compound_order(page *page)
        {
            if (!PageHead(page))
            {
                return(0); // single page
            }
            return(page->order);
        }
コード例 #3
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static bool page_is_buddy(page *page, int order)
 {
     if (PagePrivate(page) &&
         (page_order(page) == order) &&
         !PageReserved(page) &&
         page_count(page) == 0)
     {
         return(true);
     }
     return(false);
 }
コード例 #4
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        ////////////////////////////////////////////////

        public static void *page_to_virt(mem_zone *zone,
                                         page *page)
        {
            uint page_idx = 0;
            uint address  = 0;

            page_idx = (uint)(page - zone->first_page);
            address  = zone->start_addr + (page_idx * BUDDY_PAGE_SIZE);

            return((void *)address);
        }
コード例 #5
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        /// <summary>
        ///  Set the properties of the combined page
        /// </summary>
        static void prepare_compound_pages(page *page, byte order)
        {
            uint i;
            uint nr_pages = (1U << order);

            // The first page record combination page order value
            set_compound_order(page, order);
            __SetPageHead(page); // home page set head flag
            for (i = 1; i < nr_pages; i++)
            {
                page *p = page + i;
                __SetPageTail(p); // The rest of the pages set the tail flag
                p->first_page = page;
            }
        }
コード例 #6
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        public static page *buddy_get_pages(mem_zone *zone,
                                            byte order)
        {
            page *page = null;

            if (order >= BUDDY_MAX_ORDER)
            {
                BUDDY_BUG("error");
                return(null);
            }
            //TODO: lock zone->lock
            page = __alloc_page(order, zone);
            //TODO: unlock zone->lock
            return(page);
        }
コード例 #7
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
        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);
        }
コード例 #8
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
        static page *buffered_rmqueue(zone *zone, int order, int gfp_flags)
        {
            ulong flags;
            page *page = null;

            //int cold = !!(gfp_flags & __GFP_COLD);

            //if (order == 0)
            //{
            //    per_cpu_pages* pcp;

            //    pcp = &zone->pageset[get_cpu()].pcp[cold];
            //    local_irq_save(flags);
            //    if (pcp->count <= pcp->low)
            //        pcp->count += rmqueue_bulk(zone, 0,
            //                    pcp->batch, &pcp->list);
            //    if (pcp->count)
            //    {
            //        page = list_entry(pcp->list.next, page, lru);
            //        list_del(&page->lru);
            //        pcp->count--;
            //    }
            //    local_irq_restore(flags);
            //    put_cpu();
            //}

            //if (page == null)
            //{
            //    //spin_lock_irqsave(&zone->lock_, flags);
            //    page = __rmqueue(zone, order);
            //    //spin_unlock_irqrestore(&zone->lock_, flags);
            //}

            //if (page != null)
            //{
            //    BUG_ON(bad_range(zone, page));
            //    //mod_page_state_zone(zone, pgalloc, 1 << order);
            //    prep_new_page(page, order);

            //    if (gfp_flags & __GFP_ZERO)
            //        prep_zero_page(page, order, gfp_flags);

            //    if (order && (gfp_flags & __GFP_COMP))
            //        prep_compound_page(page, order);
            //}
            return(page);
        }
コード例 #9
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        /// <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);
            }
        }
コード例 #10
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        public static page *virt_to_page(mem_zone *zone, void *ptr)
        {
            uint  page_idx = 0;
            page *page     = null;
            uint  address  = (uint)ptr;

            if ((address < zone->start_addr) || (address > zone->end_addr))
            {
                //printf("start_addr=0x%lx, end_addr=0x%lx, address=0x%lx\n",
                //        zone->start_addr, zone->end_addr, address);
                BUDDY_BUG("error");
                return(null);
            }
            page_idx = (address - zone->start_addr) >> BUDDY_PAGE_SHIFT;

            page = zone->first_page + page_idx;
            return(page);
        }
コード例 #11
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        ////////////////////////////////////////////////

        /// <summary>
        /// Destroy the combined page
        /// </summary>
        static bool destroy_compound_pages(page *page, byte order)
        {
            int  bad = 0;
            uint i;
            uint nr_pages = (1U << order);

            __ClearPageHead(page);
            for (i = 1; i < nr_pages; i++)
            {
                page *p = page + i;
                if (!PageTail(p) || p->first_page != page)
                {
                    bad++;
                    BUDDY_BUG("error");
                }
                __ClearPageTail(p);
            }
            return(bad != 0);
        }
コード例 #12
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        public static void buddy_free_pages(mem_zone *zone,
                                            page *page)
        {
            byte order = compound_order(page);
            uint buddy_idx = 0, combinded_idx = 0;
            uint page_idx = (uint)(page - zone->first_page);

            //TODO: lock zone->lock
            if (PageCompound(page))
            {
                if (destroy_compound_pages(page, order))
                {
                    BUDDY_BUG("error");
                }
            }

            while (order < BUDDY_MAX_ORDER - 1)
            {
                page *buddy;
                // find and delete buddy to combine
                buddy_idx = __find_buddy_index(page_idx, order);
                buddy     = page + (buddy_idx - page_idx);
                if (!page_is_buddy(buddy, order))
                {
                    break;
                }
                list_del(&buddy->lru);
                zone->free_area[order].nr_free--;
                // remove buddy's flag and order
                rmv_page_order_buddy(buddy);
                // update page and page_idx after combined
                combinded_idx = __find_combined_index(page_idx, order);
                page          = page + (combinded_idx - page_idx);
                page_idx      = combinded_idx;
                order++;
            }
            set_page_order_buddy(page, order);
            list_add(&page->lru, &zone->free_area[order].free_list);
            zone->free_area[order].nr_free++;
            //TODO: unlock zone->lock
        }
コード例 #13
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        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);
        }
コード例 #14
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 private static bool PageCompound(page *page)
 {
     return((page->flags & ((1U << (byte)pageflags.PG_head) | (1U << (byte)pageflags.PG_tail))) != 0);
 }
コード例 #15
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static bool PagePrivate(page *page)
 {
     return(page->Flags.IsBitSet(PG_private));
 }
コード例 #16
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static uint page_order(page *page)
 {
     return(page->Private_);
 }
コード例 #17
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 static void __SetPageBuddy(page *page)
 {
     page->flags |= (1U << (byte)pageflags.PG_buddy);
 }
コード例 #18
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static void set_page_order(page *page, int order)
 {
     page->Private_ = (byte)order;
     page->Flags    = page->Flags.SetBit(PG_private);
 }
コード例 #19
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 static void set_compound_order(page *page, byte order)
 {
     //page[1].lru.prev = (void *)order;
     page->order = order;
 }
コード例 #20
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        // The page is divided into two categories: one is a single page(zero page).
        // One type is a compound page.
        // The first of the combined pages is head and the rest is tail.

        static void __SetPageHead(page *page)
        {
            page->flags |= (1U << (byte)pageflags.PG_head);
        }
コード例 #21
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 static void rmv_page_order_buddy(page *page)
 {
     page->order = 0;
     __ClearPageBuddy(page);
 }
コード例 #22
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static void rmv_page_order(page *page)
 {
     page->Flags    = page->Flags.ClearBit(PG_private);
     page->Private_ = 0;
 }
コード例 #23
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 static bool PageBuddy(page *page)
 {
     return((page->flags & (1U << (byte)pageflags.PG_buddy)) != 0);
 }
コード例 #24
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 static bool PageTail(page *page)
 {
     return((page->flags & (1U << (byte)pageflags.PG_tail)) != 0);
 }
コード例 #25
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        /**/
        static void __ClearPageHead(page *page)
        {
            page->flags &= ~(1U << (byte)pageflags.PG_head);
        }

        static void __ClearPageTail(page *page)
        {
            page->flags &= ~(1U << (byte)pageflags.PG_tail);
        }

        static void __ClearPageBuddy(page *page)
        {
            page->flags &= ~(1U << (byte)pageflags.PG_buddy);
        }

        /**/
        static bool PageHead(page *page)
        {
            return((page->flags & (1U << (byte)pageflags.PG_head)) != 0);
        }
コード例 #26
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 private static bool page_is_buddy(page *page, byte order)
 {
     return(PageBuddy(page) && (page->order == order));
 }
コード例 #27
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static uint page_count(page *page)
 {
     return(page->_count + 1);
 }
コード例 #28
0
ファイル: EmptyClass.cs プロジェクト: arakis/abanu
 static bool PageReserved(page *page)
 {
     return(page->Flags.IsBitSet(PG_reserved));
 }
コード例 #29
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
        // Set the page's order and PG_buddy flags

        static void set_page_order_buddy(page *page, byte order)
        {
            page->order = order;
            __SetPageBuddy(page);
        }
コード例 #30
0
ファイル: Alloc6.cs プロジェクト: djlw78/abanu
 static void __SetPageTail(page *page)
 {
     page->flags |= (1U << (byte)pageflags.PG_tail);
 }