📄 linux设备驱动程序学习(8)-分配内存 - linux设备驱动程序 - tekkaman ninja.htm
字号:
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN><SPAN
style="COLOR: #0000cc">(</SPAN>mempool_alloc_t<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000ff">int</SPAN> gfp_mask<SPAN
style="COLOR: #0000cc">,</SPAN> <SPAN
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN>pool_data<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR><SPAN
style="COLOR: #0000ff">typedef</SPAN> <SPAN
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">(</SPAN>mempool_free_t<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN>element<SPAN
style="COLOR: #0000cc">,</SPAN> <SPAN
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN>pool_data<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR><SPAN
style="COLOR: #ff9900">/*给 mempool_create 最后的参数
*pool_data 被传递给 alloc_fn 和 free_fn
*/</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
<P>你可编写特殊用途的函数来处理 mempool 的内存分配,但通常只需使用 slab
分配器为你处理这个任务:mempool_alloc_slab 和
mempool_free_slab的原型和上述内存池分配原型匹配,并使用
kmem_cache_alloc 和
kmem_cache_free 处理内存的分配和释放。 </P>
<P>典型的设置内存池的代码如下:
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000"><FONT face=新宋体>cache
<SPAN style="COLOR: #0000cc">=</SPAN>
kmem_cache_create<SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000cc">.</SPAN> <SPAN
style="COLOR: #0000cc">.</SPAN> <SPAN
style="COLOR: #0000cc">.</SPAN><SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN> <BR>pool <SPAN
style="COLOR: #0000cc">=</SPAN>
mempool_create<SPAN
style="COLOR: #0000cc">(</SPAN>MY_POOL_MINIMUM<SPAN
style="COLOR: #0000cc">,</SPAN>mempool_alloc_slab<SPAN
style="COLOR: #0000cc">,</SPAN>
mempool_free_slab<SPAN
style="COLOR: #0000cc">,</SPAN> cache<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN>
</FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<P>(2)创建内存池后,分配和释放对象:
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN>mempool_alloc<SPAN
style="COLOR: #0000cc">(</SPAN>mempool_t <SPAN
style="COLOR: #0000cc">*</SPAN>pool<SPAN
style="COLOR: #0000cc">,</SPAN> <SPAN
style="COLOR: #0000ff">int</SPAN> gfp_mask<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR><SPAN
style="COLOR: #0000ff">void</SPAN>
mempool_free<SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000ff">void</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN>element<SPAN
style="COLOR: #0000cc">,</SPAN> mempool_t <SPAN
style="COLOR: #0000cc">*</SPAN>pool<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE> 在创建mempool时,分配函数将被调用多次来创建预先分配的对象。因此,对
mempool_alloc
的调用是试图用分配函数请求额外的对象,如果失败,则返回预先分配的对象(如果存在)。用
mempool_free
释放对象时,若预分配的对象数目小于最小量,就将它保留在池中,否则将它返回给系统。</P>
<P>可用一下函数重定义mempool预分配对象的数量:
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000ff">int</SPAN>
mempool_resize<SPAN
style="COLOR: #0000cc">(</SPAN>mempool_t <SPAN
style="COLOR: #0000cc">*</SPAN>pool<SPAN
style="COLOR: #0000cc">,</SPAN> <SPAN
style="COLOR: #0000ff">int</SPAN>
new_min_nr<SPAN style="COLOR: #0000cc">,</SPAN>
<SPAN style="COLOR: #0000ff">int</SPAN>
gfp_mask<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR><SPAN
style="COLOR: #ff9900">/*若成功,内存池至少有 new_min_nr
个对象*/</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE> </P>
<P>(3)若不再需要内存池,则返回给系统:
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000ff">void</SPAN>
mempool_destroy<SPAN
style="COLOR: #0000cc">(</SPAN>mempool_t <SPAN
style="COLOR: #0000cc">*</SPAN>pool<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN> <BR><SPAN
style="COLOR: #ff9900">/*在销毁 mempool
之前,必须返回所有分配的对象,否则会产生
oops*/</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE>
<HR id=null>
<P></P><PRE class=programlisting><FONT color=#0000ff size=4><STRONG>get_free_page 和相关函数</STRONG></FONT></PRE><PRE class=programlisting>如果一个模块需要分配大块的内存,最好使用面向页的分配技术。</PRE>
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000">__get_free_page<SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">int</SPAN> flags<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN> <BR><SPAN
style="COLOR: #ff9900">/*返回一个指向新页的指针,
未清零该页*/</SPAN><BR><BR>get_zeroed_page<SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">int</SPAN> flags<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN> <BR><SPAN
style="COLOR: #ff9900">/*类似于__get_free_page,但用零填充该页*/</SPAN><BR><BR>__get_free_pages<SPAN
style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">int</SPAN> flags<SPAN
style="COLOR: #0000cc">,</SPAN> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">int</SPAN> order<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN> <BR><SPAN
style="COLOR: #ff9900">/*分配是若干(物理连续的)页面并返回指向该内存区域的第一个字节的指针,该内存区域未清零*/</SPAN><BR><BR><SPAN
style="COLOR: #ff9900">/*参数flags 与 kmalloc
的用法相同;<BR>参数order 是请求或释放的页数以 2
为底的对数。若其值过大(没有这么大的连续区可用),
则分配失败*/</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
<P>get_order 函数可以用来从一个整数参数 size(必须是 2 的幂) 中提取
order,函数也很简单:</P>
<P>
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000"><FONT face=新宋体><SPAN
style="COLOR: #ff9900">/* Pure 2^n version of
get_order */</SPAN><BR><SPAN
style="COLOR: #0000ff">static</SPAN> <SPAN
style="COLOR: #0000ff">__inline__</SPAN>
__attribute_const__ <SPAN
style="COLOR: #0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -