Linux中的内存分配和释放之__alloc_pages()函数分析

  在上篇文章的结尾,我们说会在接下来的文章分析分配函数的具体代码,结合我上篇文章说的伙伴机制和冷热区的概念,更好得去理解这个分配过程。好了,我们不再多说了,我们现在开始分析代码吧。

  struct page * fastcall __alloc_pages(unsigned int gfp_mask, unsigned int order,struct zonelist *zonelist)

  {
       const int wait = gfp_mask & __GFP_WAIT;//gfp_mask是申请内存时用到的控制字,这一句就是为了检测我们的控制字里面是

                                                                       //否有__GPF_WAIT这个属性,我们先来看些宏定义吧,这样你会更清楚的。

        //#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| /
                                                      __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| /
                                                      __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP)

        //#define GFP_ATOMIC (__GFP_HIGH)
        //#define GFP_NOIO (__GFP_WAIT)
        //#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
        //#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
        //#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS)
       //#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM)

     //可以看到上面的每个define都代表一个控制字,上面大部分都有__GPF_WAIT,只是GFP_ATOMIC是不包含的。如果当申请内存的控制字有__GFP_WAIT时,我们就要求一直等待到申请到内存为止,反之进程就进入睡眠状态,不进行等待。

  

   unsigned long min;
   struct zone **zones, *z;
   struct page *page;
   struct reclaim_state reclaim_state;
   struct task_struct *p = current;
   int i;
   int alloc_type;
   int do_retry;
   int can_try_harder;

 

   might_sleep_if(wait);//如果wait不等于0,则调用该函数的进程可能休眠。

   can_try_harder = (unlikely(rt_task(p)) && !in_interrupt()) || !wait;//如果当前进程是实时进程的话同时又不在软中断和硬中断

                                                                                               //或者是wait=0。这样can_try_harder=1。

                              //#define rt_task(p)  (unlikely((p)->prio < MAX_RT_PRIO))当前进程的优先级prio是否小于MAX_RT_PRIO

                       //#define MAX_RT_PRIO  MAX_USER_RT_PRIO其中MAX_USER_RT_PRIO=100。如果prio<100

                       //我们就说当前进程是实时进程。

   zones = zonelist->zones;//zonelist是struct node中的一个成员,它表示系统内所有normal内存页区的连接链表。

                                      //我们这里的zonelist->zones是这个节点的normal内存zone的struct zoon指针。我们一般把zones称为

                                    //struct zoon结构指针列表,这个表是以本次内存node的对应类型页区的struct zoon为头指针,即头指针是

                                   //指向struct zoon这个结构体的。整个表都是结构类型为struct zoon的指针。

   if (unlikely(zones[0] == NULL)) {

       return NULL;

   }//如果发现头指针为空,即没有指向struct zoon的有效指针,我们就直接返回错误。

   alloc_type = zone_idx(zones[0]);/

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值