【问题标题】:XINU - Need help understanding a system call - getstk.cXINU - 需要帮助理解系统调用 - getstk.c
【发布时间】:2013-04-21 09:09:39
【问题描述】:

我无法从概念上理解这个系统调用即将结束时发生了什么,以及为什么。我了解 getstk.c 方法返回可用空间的最高内存地址,但不了解某些代码在做什么。对此进行一些澄清会很棒。我不完全理解的代码区域用星号强调。

/* getstk.c - getstk */

#include <xinu.h>

/*------------------------------------------------------------------------
 *  getstk  -  Allocate stack memory, returning highest word address
 *------------------------------------------------------------------------
 */
char    *getstk(
          uint32        nbytes          /* size of memory requested     */
        )
{
        intmask mask;                   /* saved interrupt mask         */
        struct  memblk  *prev, *curr;   /* walk through memory list     */
        struct  memblk  *fits, *fitsprev; /* record block that fits     */

        mask = disable();
        if (nbytes == 0) {
                restore(mask);
                return (char *)SYSERR;
        }

        nbytes = (uint32) roundmb(nbytes);      /* use mblock multiples */

        prev = &memlist;
        curr = memlist.mnext;
        fits = NULL;
        fitsprev = NULL;  /* to avoid a compiler warning */

        while (curr != NULL) {                  /* scan entire list     */
                if (curr->mlength >= nbytes) {  /* record block address */
                        fits = curr;            /*   when request fits  */
                        fitsprev = prev;
                }
                prev = curr;
                curr = curr->mnext;
        }

        if (fits == NULL) {                     /* no block was found   */
                restore(mask);
                return (char *)SYSERR;
        }
        if (nbytes == fits->mlength) {          /* block is exact match */
                fitsprev->mnext = fits->mnext;
        **} else {                                /* remove top section   */
                fits->mlength -= nbytes;
                fits = (struct memblk *)((uint32)fits + fits->mlength);
        }**
        memlist.mlength -= nbytes;
        restore(mask);
        **return (char *)((uint32) fits + nbytes - sizeof(uint32));**
}

结构体 memblk 可以在这里找到:

struct  memblk  {           /* see roundmb & truncmb    */
    struct  memblk  *mnext;     /* ptr to next free memory blk  */
    uint32  mlength;        /* size of blk (includes memblk)*/
    };
extern  struct  memblk  memlist;    /* head of free memory list */

为什么他们返回 fit + nbytes - sizeof(uint32)?为什么他们将 fit(a struct) 转换为 uint32 类型?

【问题讨论】:

    标签: unix linux-kernel operating-system kernel


    【解决方案1】:
        if (nbytes == fits->mlength) {          /* block is exact match */
                fitsprev->mnext = fits->mnext;
        **} else {                                /* remove top section   */
                fits->mlength -= nbytes;
                fits = (struct memblk *)((uint32)fits + fits->mlength);
        }**
        memlist.mlength -= nbytes;
        restore(mask);
        **return (char *)((uint32) fits + nbytes - sizeof(uint32));**
    

    如果找到完美匹配,则该块将从空闲列表中删除。如果找到更大的块,则将该块分成两个块:一个空闲块nbytes小于原始块(fits-&gt;mlength -= nbytes);以及在新空闲块 (fits = (struct memblk *)((uint32)fits + fits-&gt;mlength)) 之后开始的分配块 nbytes,将由函数返回。

    为什么他们返回 fit + nbytes - sizeof(uint32)?为什么他们将 fit(a struct) 转换为 uint32 类型?

    由于这种情况下栈向下增长,函数返回一个指向栈顶的指针,也就是分配块末尾的字,即:

    (uint32)fits /* start of allocated block */ + nbytes /* size of allocated block */ - sizeof(uint32) /* size of a word */
    

    转换为(uint32) 是使用整数算术而不是指针算术,否则fits+1 将产生一个指向sizeof(struct memblk) 超出fits 的指针。转换为 (char *) 可能会更惯用。

    【讨论】:

    • 我还是不太明白为什么会这样:fits = (struct memblk *)((uint32)fits + fit->mlength);返回值仍然让我失望:(
    • @blackdemon619: fits 指向分配块的底部。当我们找到一个更大的块时,该块被分成两部分,第二部分从(uint32)fits + fits-&gt;mlength开始。
    猜你喜欢
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2022-01-15
    • 1970-01-01
    相关资源
    最近更新 更多