⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 86.html

📁 linux 0.11中文版 有注释
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<a name='L246'>      bdesc-&gt;refcnt = 0;
<a name='L247'>      bdesc-&gt;bucket_size = bdir-&gt;size;
<a name='L248'>      bdesc-&gt;page = bdesc-&gt;freeptr = (<b>void</b> *) cp = <a href='../S/94.html#L101' title='Defined at 101 in mm/memory.c.'>get_free_page</a> ();
<a name='L249'><i><font color='green'>// 如果申请内存页面操作失败,则显示出错信息,死机。</font></i>
<a name='L250'>      <b>if</b> (!cp)
<a name='L251'>        <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("Out of memory in kernel malloc()");
<a name='L252'><i><font color='green'>/* Set up the chain of free objects */</font></i>
<a name='L253'><i><font color='green'>/* 在该页空闲内存中建立空闲对象链表 */</font></i>
<a name='L254'><i><font color='green'>// 以该桶目录项指定的桶大小为对象长度,对该页内存进行划分,并使每个对象的开始4 字节设置</font></i>
<a name='L255'><i><font color='green'>// 成指向下一对象的指针。</font></i>
<a name='L256'>      <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = <a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a> / bdir-&gt;size; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &gt; 1; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>--)
<a name='L257'>        <font color='red'>{</font>
<a name='L258'>          *((<b>char</b> **) cp) = cp + bdir-&gt;size;
<a name='L259'>          cp += bdir-&gt;size;
<a name='L260'>        <font color='red'>}</font>
<a name='L261'><i><font color='green'>// 最后一个对象开始处的指针设置为0(NULL)。</font></i>
<a name='L262'><i><font color='green'>// 然后让该桶描述符的下一描述符指针字段指向对应桶目录项指针chain 所指的描述符,而桶目录的</font></i>
<a name='L263'><i><font color='green'>// chain 指向该桶描述符,也即将该描述符插入到描述符链链头处。</font></i>
<a name='L264'>      *((<b>char</b> **) cp) = 0;
<a name='L265'>      bdesc-&gt;next = bdir-&gt;chain;        <i><font color='green'>/* OK, link it in! */</font></i><i><font color='green'>/* OK,将其链入! */</font></i>
<a name='L266'>      bdir-&gt;chain = bdesc;
<a name='L267'>    <font color='red'>}</font>
<a name='L268'><i><font color='green'>// 返回指针即等于该描述符对应页面的当前空闲指针。然后调整该空闲空间指针指向下一个空闲对象,</font></i>
<a name='L269'><i><font color='green'>// 并使描述符中对应页面中对象引用计数增1。</font></i>
<a name='L270'>  retval = (<b>void</b> *) bdesc-&gt;freeptr;
<a name='L271'>  bdesc-&gt;freeptr = *((<b>void</b> **) retval);
<a name='L272'>  bdesc-&gt;refcnt++;
<a name='L273'><i><font color='green'>// 最后开放中断,并返回指向空闲内存对象的指针。</font></i>
<a name='L274'>  <a href='../S/25.html#L14' title='Defined at 14 in include/asm/system.h.'>sti</a> ();                       <i><font color='green'>/* OK, we're safe again */</font></i><i><font color='green'>/* OK,现在我们又安全了 */</font></i>
<a name='L275'>  <b>return</b> (retval);
<a name='L276'><font color='red'>}</font>
<a name='L277'>
<a name='L278'><i><font color='green'>/*</font></i>
<a name='L279'><i><font color='green'>* Here is the free routine. If you know the size of the object that you</font></i>
<a name='L280'><i><font color='green'>* are freeing, then free_s() will use that information to speed up the</font></i>
<a name='L281'><i><font color='green'>* search for the bucket descriptor.</font></i>
<a name='L282'><i><font color='green'>*</font></i>
<a name='L283'><i><font color='green'>* We will #define a macro so that "free(x)" is becomes "free_s(x, 0)"</font></i>
<a name='L284'><i><font color='green'>*/</font></i>
<a name='L285'><i><font color='green'>/*</font></i>
<a name='L286'><i><font color='green'>* 下面是释放子程序。如果你知道释放对象的大小,则free_s()将使用该信息加速</font></i>
<a name='L287'><i><font color='green'>* 搜寻对应桶描述符的速度。</font></i>
<a name='L288'><i><font color='green'>*</font></i>
<a name='L289'><i><font color='green'></font></i>
<a name='L290'><i><font color='green'>* 我们将定义一个宏,使得"free(x)"成为"free_s(x, 0)"。</font></i>
<a name='L291'><i><font color='green'>*/</font></i>
<a name='L292'><i><font color='green'>//// 释放存储桶对象。</font></i>
<a name='L293'><i><font color='green'>// 参数:obj - 对应对象指针;size - 大小。</font></i>
<a name='L294'><b>void</b>
<a name='L295'><a href='../R/470.html' title='Multiple refered from 2 places.'>free_s</a> (<b>void</b> *obj, <b>int</b> size)
<a name='L296'><font color='red'>{</font>
<a name='L297'>  <b>void</b> *page;
<a name='L298'>  <b>struct</b> _bucket_dir *bdir;
<a name='L299'>  <b>struct</b> bucket_desc *bdesc, *prev;
<a name='L300'>
<a name='L301'><i><font color='green'>/* Calculate what page this object lives in */</font></i>
<a name='L302'><i><font color='green'>/* 计算该对象所在的页面 */</font></i>
<a name='L303'>  page = (<b>void</b> *) ((<b>unsigned</b> <b>long</b>) obj &amp; 0xfffff000);
<a name='L304'><i><font color='green'>/* Now search the buckets looking for that page */</font></i>
<a name='L305'><i><font color='green'>/* 现在搜索存储桶目录项所链接的桶描述符,寻找该页面 */</font></i>
<a name='L306'><i><font color='green'>//</font></i>
<a name='L307'>  <b>for</b> (bdir = bucket_dir; bdir-&gt;size; bdir++)
<a name='L308'>    <font color='red'>{</font>
<a name='L309'>      prev = 0;
<a name='L310'><i><font color='green'>/* If size is zero then this conditional is always false */</font></i>
<a name='L311'><i><font color='green'>/* 如果参数size 是0,则下面条件肯定是false */</font></i>
<a name='L312'>      <b>if</b> (bdir-&gt;size &lt; size)
<a name='L313'>        <b>continue</b>;
<a name='L314'><i><font color='green'>// 搜索对应目录项中链接的所有描述符,查找对应页面。如果某描述符页面指针等于page 则表示找到</font></i>
<a name='L315'><i><font color='green'>// 了相应的描述符,跳转到found。如果描述符不含有对应page,则让描述符指针prev 指向该描述符。</font></i>
<a name='L316'>      <b>for</b> (bdesc = bdir-&gt;chain; bdesc; bdesc = bdesc-&gt;next)
<a name='L317'>        <font color='red'>{</font>
<a name='L318'>          <b>if</b> (bdesc-&gt;page == page)
<a name='L319'>            <b>goto</b> found;
<a name='L320'>          prev = bdesc;
<a name='L321'>        <font color='red'>}</font>
<a name='L322'>    <font color='red'>}</font>
<a name='L323'><i><font color='green'>// 若搜索了对应目录项的所有描述符都没有找到指定的页面,则显示出错信息,死机。</font></i>
<a name='L324'>  <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("Bad address passed to kernel free_s()");
<a name='L325'>found:
<a name='L326'><i><font color='green'>// 找到对应的桶描述符后,首先关中断。然后将该对象内存块链入空闲块对象链表中,并使该描述符</font></i>
<a name='L327'><i><font color='green'>// 的对象引用计数减1。</font></i>
<a name='L328'>  <a href='../S/25.html#L15' title='Defined at 15 in include/asm/system.h.'>cli</a> ();                       <i><font color='green'>/* To avoid race conditions */</font></i><i><font color='green'>/* 为了避免竞争条件 */</font></i>
<a name='L329'>  *((<b>void</b> **) obj) = bdesc-&gt;freeptr;
<a name='L330'>  bdesc-&gt;freeptr = obj;
<a name='L331'>  bdesc-&gt;refcnt--;
<a name='L332'><i><font color='green'>// 如果引用计数已等于0,则我们就可以释放对应的内存页面和该桶描述符。</font></i>
<a name='L333'>  <b>if</b> (bdesc-&gt;refcnt == 0)
<a name='L334'>    <font color='red'>{</font>
<a name='L335'><i><font color='green'>/*</font></i>
<a name='L336'><i><font color='green'>* We need to make sure that prev is still accurate. It</font></i>
<a name='L337'><i><font color='green'>* may not be, if someone rudely interrupted us....</font></i>
<a name='L338'><i><font color='green'>*/</font></i>
<a name='L339'><i><font color='green'>/*</font></i>
<a name='L340'><i><font color='green'>* 我们需要确信prev 仍然是正确的,若某程序粗鲁地中断了我们</font></i>
<a name='L341'><i><font color='green'>* 就有可能不是了。</font></i>
<a name='L342'><i><font color='green'>*/</font></i>
<a name='L343'><i><font color='green'>// 如果prev 已经不是搜索到的描述符的前一个描述符,则重新搜索当前描述符的前一个描述符。</font></i>
<a name='L344'>      <b>if</b> ((prev &amp;&amp; (prev-&gt;next != bdesc)) ||
<a name='L345'>          (!prev &amp;&amp; (bdir-&gt;chain != bdesc)))
<a name='L346'>        <b>for</b> (prev = bdir-&gt;chain; prev; prev = prev-&gt;next)
<a name='L347'>
<a name='L348'>          <b>if</b> (prev-&gt;next == bdesc)
<a name='L349'>            <b>break</b>;
<a name='L350'><i><font color='green'>// 如果找到该前一个描述符,则从描述符链中删除当前描述符。</font></i>
<a name='L351'>      <b>if</b> (prev)
<a name='L352'>        prev-&gt;next = bdesc-&gt;next;
<a name='L353'><i><font color='green'>// 如果prev==NULL,则说明当前一个描述符是该目录项首个描述符,也即目录项中chain 应该直接</font></i>
<a name='L354'><i><font color='green'>// 指向当前描述符bdesc,否则表示链表有问题,则显示出错信息,死机。因此,为了将当前描述符</font></i>
<a name='L355'><i><font color='green'>// 从链表中删除,应该让chain 指向下一个描述符。</font></i>
<a name='L356'>      <b>else</b>
<a name='L357'>        <font color='red'>{</font>
<a name='L358'>          <b>if</b> (bdir-&gt;chain != bdesc)
<a name='L359'>            <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("malloc bucket chains corrupted");
<a name='L360'>          bdir-&gt;chain = bdesc-&gt;next;
<a name='L361'>        <font color='red'>}</font>
<a name='L362'><i><font color='green'>// 释放当前描述符所操作的内存页面,并将该描述符插入空闲描述符链表开始处。</font></i>
<a name='L363'>      <a href='../S/94.html#L130' title='Defined at 130 in mm/memory.c.'>free_page</a> ((<b>unsigned</b> <b>long</b>) bdesc-&gt;page);
<a name='L364'>      bdesc-&gt;next = free_bucket_desc;
<a name='L365'>      free_bucket_desc = bdesc;
<a name='L366'>    <font color='red'>}</font>
<a name='L367'><i><font color='green'>// 开中断,返回。</font></i>
<a name='L368'>  <a href='../S/25.html#L14' title='Defined at 14 in include/asm/system.h.'>sti</a> ();
<a name='L369'>  <b>return</b>;
<a name='L370'><font color='red'>}</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L154'>[^]</a><a href='#L295'>[v]</a><a href='#TOP'>[top]</a>[bottom]<a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -