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

📄 86.html

📁 linux 0.11中文版 有注释
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<html>
<head>
<title>lib/malloc.c</title>
<meta name='robots' content='noindex,nofollow'>
<meta name='generator' content='GLOBAL-5.4.1'>
</head>
<body text='#191970' bgcolor='#f5f5dc' vlink='gray'>
<a name='TOP'><h2><a href='../mains.html'>root</a>/<a href='../files/108.html'>lib</a>/malloc.c</h2>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L154'>[^]</a><a href='#L295'>[v]</a>[top]<a href='#BOTTOM'>[bottom]</a><a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
<hr>
<h2>DEFINITIONS</h2>
This source file includes following definitions.
<ol>
<li><a href='#L154' title='Defined at 154.'>init_bucket_desc</a>
<li><a href='#L187' title='Defined at 187.'>malloc</a>
<li><a href='#L295' title='Defined at 295.'>free_s</a>
</ol>
<hr>
<pre>
<a name='L1'><i><font color='green'>/*</font></i>
<a name='L2'><i><font color='green'>* malloc.c --- a general purpose kernel memory allocator for Linux.</font></i>
<a name='L3'><i><font color='green'>*</font></i>
<a name='L4'><i><font color='green'>* Written by Theodore Ts'o (tytso@mit.edu), 11/29/91</font></i>
<a name='L5'><i><font color='green'>*</font></i>
<a name='L6'><i><font color='green'>* This routine is written to be as fast as possible, so that it</font></i>
<a name='L7'><i><font color='green'>* can be called from the interrupt level.</font></i>
<a name='L8'><i><font color='green'>*</font></i>
<a name='L9'><i><font color='green'>* Limitations: maximum size of memory we can allocate using this routine</font></i>
<a name='L10'><i><font color='green'>* is 4k, the size of a page in Linux.</font></i>
<a name='L11'><i><font color='green'>*</font></i>
<a name='L12'><i><font color='green'>* The general game plan is that each page (called a bucket) will only hold</font></i>
<a name='L13'><i><font color='green'>* objects of a given size. When all of the object on a page are released,</font></i>
<a name='L14'><i><font color='green'>* the page can be returned to the general free pool. When malloc() is</font></i>
<a name='L15'><i><font color='green'>* called, it looks for the smallest bucket size which will fulfill its</font></i>
<a name='L16'><i><font color='green'>* request, and allocate a piece of memory from that bucket pool.</font></i>
<a name='L17'><i><font color='green'>*</font></i>
<a name='L18'><i><font color='green'>* Each bucket has as its control block a bucket descriptor which keeps</font></i>
<a name='L19'><i><font color='green'>* track of how many objects are in use on that page, and the free list</font></i>
<a name='L20'><i><font color='green'>* for that page. Like the buckets themselves, bucket descriptors are</font></i>
<a name='L21'><i><font color='green'>* stored on pages requested from get_free_page(). However, unlike buckets,</font></i>
<a name='L22'><i><font color='green'>* pages devoted to bucket descriptor pages are never released back to the</font></i>
<a name='L23'><i><font color='green'>* system. Fortunately, a system should probably only need 1 or 2 bucket</font></i>
<a name='L24'><i><font color='green'>* descriptor pages, since a page can hold 256 bucket descriptors (which</font></i>
<a name='L25'><i><font color='green'>* corresponds to 1 megabyte worth of bucket pages.) If the kernel is using</font></i>
<a name='L26'><i><font color='green'>* that much allocated memory, it's probably doing something wrong. :-)</font></i>
<a name='L27'><i><font color='green'>*</font></i>
<a name='L28'><i><font color='green'>* Note: malloc() and free() both call get_free_page() and free_page()</font></i>
<a name='L29'><i><font color='green'>* in sections of code where interrupts are turned off, to allow</font></i>
<a name='L30'><i><font color='green'>* malloc() and free() to be safely called from an interrupt routine.</font></i>
<a name='L31'><i><font color='green'>* (We will probably need this functionality when networking code,</font></i>
<a name='L32'><i><font color='green'>* particularily things like NFS, is added to Linux.) However, this</font></i>
<a name='L33'><i><font color='green'>* presumes that get_free_page() and free_page() are interrupt-level</font></i>
<a name='L34'><i><font color='green'>* safe, which they may not be once paging is added. If this is the</font></i>
<a name='L35'><i><font color='green'>* case, we will need to modify malloc() to keep a few unused pages</font></i>
<a name='L36'><i><font color='green'>* "pre-allocated" so that it can safely draw upon those pages if</font></i>
<a name='L37'><i><font color='green'>* it is called from an interrupt routine.</font></i>
<a name='L38'><i><font color='green'>*</font></i>
<a name='L39'><i><font color='green'>* Another concern is that get_free_page() should not sleep; if it</font></i>
<a name='L40'><i><font color='green'>* does, the code is carefully ordered so as to avoid any race</font></i>
<a name='L41'><i><font color='green'>* conditions. The catch is that if malloc() is called re-entrantly,</font></i>
<a name='L42'><i><font color='green'>* there is a chance that unecessary pages will be grabbed from the</font></i>
<a name='L43'><i><font color='green'>* system. Except for the pages for the bucket descriptor page, the</font></i>
<a name='L44'><i><font color='green'>* extra pages will eventually get released back to the system, though,</font></i>
<a name='L45'><i><font color='green'>* so it isn't all that bad.</font></i>
<a name='L46'><i><font color='green'>*/</font></i>
<a name='L47'>
<a name='L48'><i><font color='green'>/*</font></i>
<a name='L49'><i><font color='green'>* malloc.c - Linux 的通用内核内存分配函数。</font></i>
<a name='L50'><i><font color='green'>*</font></i>
<a name='L51'><i><font color='green'>* 由Theodore Ts'o 编制 (tytso@mit.edu), 11/29/91</font></i>
<a name='L52'><i><font color='green'>*</font></i>
<a name='L53'><i><font color='green'>* 该函数被编写成尽可能地快,从而可以从中断层调用此函数。</font></i>
<a name='L54'><i><font color='green'>*</font></i>
<a name='L55'><i><font color='green'>* 限制:使用该函数一次所能分配的最大内存是4k,也即Linux 中内存页面的大小。</font></i>
<a name='L56'><i><font color='green'>*</font></i>
<a name='L57'><i><font color='green'>* 编写该函数所遵循的一般规则是每页(被称为一个存储桶)仅分配所要容纳对象的大小。</font></i>
<a name='L58'><i><font color='green'>* 当一页上的所有对象都释放后,该页就可以返回通用空闲内存池。当malloc()被调用</font></i>
<a name='L59'><i><font color='green'>* 时,它会寻找满足要求的最小的存储桶,并从该存储桶中分配一块内存。</font></i>
<a name='L60'><i><font color='green'>*</font></i>
<a name='L61'><i><font color='green'>* 每个存储桶都有一个作为其控制用的存储桶描述符,其中记录了页面上有多少对象正被</font></i>
<a name='L62'><i><font color='green'>* 使用以及该页上空闲内存的列表。就象存储桶自身一样,存储桶描述符也是存储在使用</font></i>
<a name='L63'><i><font color='green'>* get_free_page()申请到的页面上的,但是与存储桶不同的是,桶描述符所占用的页面</font></i>
<a name='L64'><i><font color='green'>* 将不再会释放给系统。幸运的是一个系统大约只需要1 到2 页的桶描述符页面,因为一</font></i>
<a name='L65'><i><font color='green'>* 个页面可以存放256 个桶描述符(对应1MB 内存的存储桶页面)。如果系统为桶描述符分</font></i>
<a name='L66'><i><font color='green'></font></i>
<a name='L67'><i><font color='green'>* 配了许多内存,那么肯定系统什么地方出了问题?。</font></i>
<a name='L68'><i><font color='green'>*</font></i>
<a name='L69'><i><font color='green'>* 注意!malloc()和free()两者关闭了中断的代码部分都调用了get_free_page()和</font></i>
<a name='L70'><i><font color='green'>* free_page()函数,以使malloc()和free()可以安全地被从中断程序中调用</font></i>
<a name='L71'><i><font color='green'>* (当网络代码,尤其是NFS 等被加入到Linux 中时就可能需要这种功能)。但前</font></i>
<a name='L72'><i><font color='green'>* 提是假设get_free_page()和free_page()是可以安全地在中断级程序中使用的,</font></i>
<a name='L73'><i><font color='green'>* 这在一旦加入了分页处理之后就可能不是安全的。如果真是这种情况,那么我们</font></i>
<a name='L74'><i><font color='green'>* 就需要修改malloc()来“预先分配”几页不用的内存,如果malloc()和free()</font></i>
<a name='L75'><i><font color='green'>* 被从中断程序中调用时就可以安全地使用这些页面。</font></i>
<a name='L76'><i><font color='green'>*</font></i>
<a name='L77'><i><font color='green'>* 另外需要考虑到的是get_free_page()不应该睡眠;如果会睡眠的话,则为了防止</font></i>
<a name='L78'><i><font color='green'>* 任何竞争条件,代码需要仔细地安排顺序。 关键在于如果malloc()是可以重入地</font></i>
<a name='L79'><i><font color='green'>* 被调用的话,那么就会存在不必要的页面被从系统中取走的机会。除了用于桶描述</font></i>
<a name='L80'><i><font color='green'>* 符的页面,这些额外的页面最终会释放给系统,所以并不是象想象的那样不好。</font></i>
<a name='L81'><i><font color='green'>*/</font></i>
<a name='L82'><font color='darkred'>#include</font> &lt;<a href='34.html'>linux/kernel.h</a>&gt;       <i><font color='green'>// 内核头文件。含有一些内核常用函数的原形定义。</font></i>
<a name='L83'><font color='darkred'>#include</font> &lt;<a href='35.html'>linux/mm.h</a>&gt;           <i><font color='green'>// 内存管理头文件。含有页面大小定义和一些页面释放函数原型。</font></i>
<a name='L84'><font color='darkred'>#include</font> &lt;<a href='25.html'>asm/system.h</a>&gt;         <i><font color='green'>// 系统头文件。定义了设置或修改描述符/中断门等的嵌入式汇编宏。</font></i>
<a name='L85'>
<a name='L86'><i><font color='green'>// 存储桶描述符结构。</font></i>
<a name='L87'><b>struct</b> bucket_desc
<a name='L88'><font color='red'>{</font>                               <i><font color='green'>/* 16 bytes */</font></i>
<a name='L89'>  <b>void</b> *page;                   <i><font color='green'>// 该桶描述符对应的内存页面指针。</font></i>
<a name='L90'>  <b>struct</b> bucket_desc *next;     <i><font color='green'>// 下一个描述符指针。</font></i>
<a name='L91'>  <b>void</b> *freeptr;                <i><font color='green'>// 指向本桶中空闲内存位置的指针。</font></i>
<a name='L92'>  <b>unsigned</b> <b>short</b> refcnt;        <i><font color='green'>// 引用计数。</font></i>
<a name='L93'>  <b>unsigned</b> <b>short</b> bucket_size;   <i><font color='green'>// 本描述符对应存储桶的大小。</font></i>
<a name='L94'><font color='red'>}</font>;
<a name='L95'>
<a name='L96'><i><font color='green'>// 存储桶描述符目录结构。</font></i>
<a name='L97'><b>struct</b> _bucket_dir
<a name='L98'><font color='red'>{</font>                               <i><font color='green'>/* 8 bytes */</font></i>
<a name='L99'>  <b>int</b> size;                     <i><font color='green'>// 该存储桶的大小(字节数)。</font></i>
<a name='L100'>  <b>struct</b> bucket_desc *chain;    <i><font color='green'>// 该存储桶目录项的桶描述符链表指针。</font></i>
<a name='L101'><font color='red'>}</font>;
<a name='L102'>
<a name='L103'><i><font color='green'>/*</font></i>
<a name='L104'><i><font color='green'>* The following is the where we store a pointer to the first bucket</font></i>
<a name='L105'><i><font color='green'>* descriptor for a given size.</font></i>
<a name='L106'><i><font color='green'>*</font></i>
<a name='L107'><i><font color='green'>* If it turns out that the Linux kernel allocates a lot of objects of a</font></i>
<a name='L108'><i><font color='green'>* specific size, then we may want to add that specific size to this list,</font></i>
<a name='L109'><i><font color='green'>* since that will allow the memory to be allocated more efficiently.</font></i>
<a name='L110'><i><font color='green'>* However, since an entire page must be dedicated to each specific size</font></i>
<a name='L111'><i><font color='green'>* on this list, some amount of temperance must be exercised here.</font></i>
<a name='L112'><i><font color='green'>*</font></i>
<a name='L113'><i><font color='green'>* Note that this list *must* be kept in order.</font></i>

⌨️ 快捷键说明

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