Unix XINU-需要了解系统调用的帮助-getstk.c
我在概念上理解这个系统调用即将结束时发生的事情以及原因方面遇到了困难。我理解getstk.c方法返回可用空间的最高内存地址,但不理解某些代码在做什么。在这一点上搞清楚就好了。我不完全理解的代码区域用星号强调Unix XINU-需要了解系统调用的帮助-getstk.c,unix,linux-kernel,operating-system,kernel,Unix,Linux Kernel,Operating System,Kernel,我在概念上理解这个系统调用即将结束时发生的事情以及原因方面遇到了困难。我理解getstk.c方法返回可用空间的最高内存地址,但不理解某些代码在做什么。在这一点上搞清楚就好了。我不完全理解的代码区域用星号强调 /* getstk.c - getstk */ #include <xinu.h> /*------------------------------------------------------------------------ * getstk - Alloca
/* 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));**
}
为什么他们要返回fits+n字节-sizeof(uint32)?为什么要将配合(结构)铸造到uint32型上
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->mllength-=nbytes
);以及在新空闲块(fits=(struct memblk*)((uint32)fits+fits->mlength)
)之后开始的一个分配的n字节块,该块将由函数返回
为什么他们要返回fits+n字节-sizeof(uint32)?为什么要将配合(结构)铸造到uint32型上
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));**
在这种情况下,由于堆栈向下生长,因此函数返回指向堆栈顶部的指针,即位于所分配块末尾的字,即:
(uint32)fits /* start of allocated block */ + nbytes /* size of allocated block */ - sizeof(uint32) /* size of a word */
对(uint32)
的强制转换是使用整数算术而不是指针算术,否则fits+1
将生成指向sizeof(struct memblk)
的指针。转换到(char*)
可能更为惯用。我仍然不太明白为什么会这样做:fits=(struct memblk*)((uint32)fits+fits->mlength);返回值也让我感到不舒服:(@blackdemon619:fits
指向分配块的底部。当我们找到一个较大的块时,该块被一分为二,第二部分从(uint32)fits+fits->mlength
开始。