📄 lib0033.html
字号:
<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>System Call Interface and Porting Issues</title>
<link rel="STYLESHEET" type="text/css" href="images/xpolecat.css">
<link rel="STYLESHEET" type="text/css" href="images/ie.content.books24x7.css">
</head>
<body >
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<td><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td valign="top" class="v2" align="right"><div STYLE="MARGIN-RIGHT: 0.15in"><a href="LiB0032.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0034.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr>
</table>
<div class="chapter">
<a name="ch04"></a>
<div class="section">
<h2 class="first-section-title"><a name="422"></a><a name="ch04lev1sec2"></a>System Call Interface and Porting Issues</h2><p class="first-para">The C standard library <span class="fixed">malloc()</span> and <span class="fixed">free()</span> functions are procedures that execute in user mode. Inevitably, they rely on native library routines to do the actual dirty work of allocating and releasing memory. The native libraries, in turn, make use of the system call gate to access system calls that reside in kernel mode. This dance step is displayed in <a class="internaljump" href="#ch04fig01">Figure 4.1</a>.</p>
<div class="figure">
<a name="423"></a><a name="ch04fig01"></a><span class="figuremediaobject"><a href="images/fig236%5F01%5F0%2Ejpg" NAME="IMG_68" target="_parent"><img src="images/fig236_01.jpg" height="150" width="350" alt="Click To expand" border="0"></a></span>
<br style="line-height: 1">
<span class="figure-title"><span class="figure-titlelabel">Figure 4.1</span></span>
</div>
<a name="424"></a><a name="IDX-209"></a>
<p class="para">The specific native library functions that <span class="fixed">malloc()</span> and <span class="fixed">free()</span> invoke will differ from one operating system to the next. On UNIX platforms, <span class="fixed">malloc()</span> and <span class="fixed">free()</span> end up invoking the <span class="fixed">brk()</span> system call through its native library wrapper function, <span class="fixed">sbrk()</span>. <a class="internaljump" href="#ch04fig02">Figure 4.2</a> shows an example of how this works in MINIX.</p>
<div class="figure">
<a name="425"></a><a name="ch04fig02"></a><span class="figuremediaobject"><a href="images/fig237%5F01%5F0%2Ejpg" NAME="IMG_69" target="_parent"><img src="images/fig237_01.jpg" height="151" width="350" alt="Click To expand" border="0"></a></span>
<br style="line-height: 1">
<span class="figure-title"><span class="figure-titlelabel">Figure 4.2</span></span>
</div>
<p class="para">Because I am developing on Windows, instead of <span class="fixed">sbrk()</span> I will be using the Win32 <span class="fixed">HeapXXX()</span> functions to act as my touch point to the kernel. Here are the specific Win32 routines that I will be invoking:</p>
<div class="informalexample">
<pre class="literallayout">
HANDLE GetProcessHeap(VOID);
LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes);
LPVOID HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem,
DWORD dwBytes);
BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
</pre>
</div>
<p class="para">Here is a short example to give you a feel for how these functions are utilized. In the following example, I allocate a 2MB heap and populate it with the letter "a." Then I increase the size of the heap by 1MB (without moving the original memory block) and repopulate it all with "a."</p>
<div class="informalexample">
<pre class="literallayout">
<span style="background-color:d9d9d9">/* --heapDemo.c-- */</span>
<span style="background-color:d9d9d9">#include<stdio.h></span>
<span style="background-color:d9d9d9">#include<windows.h></span>
<span style="background-color:d9d9d9">#define MB 1048576</span>
<span style="background-color:d9d9d9">#define U1 unsigned char</span>
<span style="background-color:d9d9d9">#define U4 unsigned long</span>
<span style="background-color:d9d9d9">void main()</span>
<span style="background-color:d9d9d9">{</span>
<span style="background-color:d9d9d9">HANDLE handle;</span>
<span style="background-color:d9d9d9">U4 *ptr;</span>
<span style="background-color:d9d9d9">U1 *cptr;</span><a name="426"></a><a name="IDX-210"></a>
<span style="background-color:d9d9d9">int i;</span>
<span style="background-color:d9d9d9">handle = GetProcessHeap();</span>
<span style="background-color:d9d9d9">if(handle==NULL)</span>
<span style="background-color:d9d9d9">{</span>
<span style="background-color:d9d9d9">printf("could not get heap handle\n");</span>
<span style="background-color:d9d9d9">return;</span>
<span style="background-color:d9d9d9">}</span>
<span style="background-color:d9d9d9">/*allocate and fill 2MB with 'a' character----------------*/</span>
<span style="background-color:d9d9d9">ptr = HeapAlloc(handle,HEAP_ZERO_MEMORY,2*MB);</span>
<span style="background-color:d9d9d9">if(ptr==NULL)</span>
<span style="background-color:d9d9d9">{</span>
<span style="background-color:d9d9d9">printf("HeapAlloc() failed\n");</span>
<span style="background-color:d9d9d9">return;</span>
<span style="background-color:d9d9d9">}</span>
<span style="background-color:d9d9d9">printf("address=%p\n",ptr);</span>
<span style="background-color:d9d9d9">printf("size=%lu\n",HeapSize(handle,HEAP_NO_SERIALIZE,ptr));</span>
<span style="background-color:d9d9d9">cptr = (U1*)ptr;</span>
<span style="background-color:d9d9d9">for(i=0;i<2*MB;i++){ cptr[i] = 'a'; }</span>
<span style="background-color:d9d9d9">/*increase heap by 1MB but do NOT move and fill with 'a'--*/</span>
<span style="background-color:d9d9d9">ptr = HeapReAlloc(handle,HEAP_REALLOC_IN_PLACE_ONLY,</span>
<span style="background-color:d9d9d9">ptr,3*MB);</span>
<span style="background-color:d9d9d9">if(ptr==NULL)</span>
<span style="background-color:d9d9d9">{</span>
<span style="background-color:d9d9d9">printf("HeapAlloc() failed\n");</span>
<span style="background-color:d9d9d9">return;</span>
<span style="background-color:d9d9d9">}</span>
<span style="background-color:d9d9d9">printf("address=%p\n",ptr);</span>
<span style="background-color:d9d9d9">printf("size=%lu\n",HeapSize(handle,HEAP_NO_SERIALIZE,ptr));</span>
<span style="background-color:d9d9d9">cptr = (U1*)ptr;</span>
<span style="background-color:d9d9d9">for(i=0;i<3*MB;i++){ cptr[i] = 'a'; }</span>
<span style="background-color:d9d9d9">/*set the heap free ---------------------------------------*/</span>
<span style="background-color:d9d9d9">if(HeapFree(handle,HEAP_NO_SERIALIZE,ptr)==0)</span>
<span style="background-color:d9d9d9">{</span>
<span style="background-color:d9d9d9">printf("HeapFree() failed\n");</span>
<span style="background-color:d9d9d9">return;</span>
<span style="background-color:d9d9d9">}</span><a name="427"></a><a name="IDX-211"></a>
<span style="background-color:d9d9d9">return;</span>
<span style="background-color:d9d9d9">}</span>
</pre>
</div>
<table border="0" cellspacing="0" cellpadding="0" class="note">
<tr>
<td valign="top" class="admon-check"></td><td valign="top" class="admon-title">Note </td><td valign="top" class="admon-body">
<p class="first-para">I decided on Windows because it is the most accessible platform. Everyone and his brother has at least one Windows box sitting around somewhere. The documentation for Windows is better also. Linux and BSD variants tend to require a little more investment in terms of the learning curve, so I decided on Windows in an effort to keep the audience as broad as possible.</p>
</td>
</tr>
</table>
<p class="para">If you value portability above more direct access to the kernel, you could probably get away with using <span class="fixed">malloc()</span> to allocate yourself a large "heap," though (see <a class="internaljump" href="#ch04fig03">Figure 4.3</a>) this would add an extra layer of code between the memory management that I am going to implement and the operating system.</p>
<div class="figure">
<a name="428"></a><a name="ch04fig03"></a><span class="figuremediaobject"><a href="images/fig239%5F01%5F0%2Ejpg" NAME="IMG_70" target="_parent"><img src="images/fig239_01.jpg" height="139" width="350" alt="Click To expand" border="0"></a></span>
<br style="line-height: 1">
<span class="figure-title"><span class="figure-titlelabel">Figure 4.3</span></span>
</div>
<a></a>
</div>
</div>
</div>
</div>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<td><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td valign="top" class="v2" align="right"><div STYLE="MARGIN-RIGHT: 0.15in"><a href="LiB0032.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0034.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -