<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-cn">
		<id>http://wiki.ywrobot.net/index.php?action=history&amp;feed=atom&amp;title=Malloc.c</id>
		<title>Malloc.c - 版本历史</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.ywrobot.net/index.php?action=history&amp;feed=atom&amp;title=Malloc.c"/>
		<link rel="alternate" type="text/html" href="http://wiki.ywrobot.net/index.php?title=Malloc.c&amp;action=history"/>
		<updated>2026-05-14T11:01:13Z</updated>
		<subtitle>本wiki的该页面的版本历史</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>http://wiki.ywrobot.net/index.php?title=Malloc.c&amp;diff=49&amp;oldid=prev</id>
		<title>YWrobot WM：创建页面，内容为“&lt;pre style=&quot;color:blue&quot;&gt; /* Copyright (c) 2002, 2004, 2010 Joerg Wunsch    Copyright (c) 2010  Gerben van den Broeke    All rights reserved.     Redistribution and u...”</title>
		<link rel="alternate" type="text/html" href="http://wiki.ywrobot.net/index.php?title=Malloc.c&amp;diff=49&amp;oldid=prev"/>
				<updated>2016-04-25T01:55:12Z</updated>
		
		<summary type="html">&lt;p&gt;创建页面，内容为“&amp;lt;pre style=&amp;quot;color:blue&amp;quot;&amp;gt; /* Copyright (c) 2002, 2004, 2010 Joerg Wunsch    Copyright (c) 2010  Gerben van den Broeke    All rights reserved.     Redistribution and u...”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre style=&amp;quot;color:blue&amp;quot;&amp;gt;&lt;br /&gt;
/* Copyright (c) 2002, 2004, 2010 Joerg Wunsch&lt;br /&gt;
   Copyright (c) 2010  Gerben van den Broeke&lt;br /&gt;
   All rights reserved.&lt;br /&gt;
&lt;br /&gt;
   Redistribution and use in source and binary forms, with or without&lt;br /&gt;
   modification, are permitted provided that the following conditions are met:&lt;br /&gt;
&lt;br /&gt;
   * Redistributions of source code must retain the above copyright&lt;br /&gt;
     notice, this list of conditions and the following disclaimer.&lt;br /&gt;
&lt;br /&gt;
   * Redistributions in binary form must reproduce the above copyright&lt;br /&gt;
     notice, this list of conditions and the following disclaimer in&lt;br /&gt;
     the documentation and/or other materials provided with the&lt;br /&gt;
     distribution.&lt;br /&gt;
&lt;br /&gt;
   * Neither the name of the copyright holders nor the names of&lt;br /&gt;
     contributors may be used to endorse or promote products derived&lt;br /&gt;
     from this software without specific prior written permission.&lt;br /&gt;
&lt;br /&gt;
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot;&lt;br /&gt;
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&lt;br /&gt;
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE&lt;br /&gt;
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE&lt;br /&gt;
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR&lt;br /&gt;
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF&lt;br /&gt;
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS&lt;br /&gt;
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN&lt;br /&gt;
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)&lt;br /&gt;
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE&lt;br /&gt;
  POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
/* $Id: malloc.c 2149 2010-06-09 20:45:37Z joerg_wunsch $ */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;sectionname.h&amp;quot;&lt;br /&gt;
#include &amp;quot;stdlib_private.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Exported interface:&lt;br /&gt;
 *&lt;br /&gt;
 * When extending the data segment, the allocator will not try to go&lt;br /&gt;
 * beyond the current stack limit, decreased by __malloc_margin bytes.&lt;br /&gt;
 * Thus, all possible stack frames of interrupt routines that could&lt;br /&gt;
 * interrupt the current function, plus all further nested function&lt;br /&gt;
 * calls must not require more stack space, or they'll risk to collide&lt;br /&gt;
 * with the data segment.&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
/* May be changed by the user only before the first malloc() call.  */&lt;br /&gt;
&lt;br /&gt;
size_t __malloc_margin = 128;&lt;br /&gt;
char *__malloc_heap_start = &amp;amp;__heap_start;&lt;br /&gt;
char *__malloc_heap_end = &amp;amp;__heap_end;&lt;br /&gt;
&lt;br /&gt;
char *__brkval;&lt;br /&gt;
struct __freelist *__flp;&lt;br /&gt;
&lt;br /&gt;
ATTRIBUTE_CLIB_SECTION&lt;br /&gt;
void *&lt;br /&gt;
malloc(size_t len)&lt;br /&gt;
{&lt;br /&gt;
	struct __freelist *fp1, *fp2, *sfp1, *sfp2;&lt;br /&gt;
	char *cp;&lt;br /&gt;
	size_t s, avail;&lt;br /&gt;
&lt;br /&gt;
	/*&lt;br /&gt;
	 * Our minimum chunk size is the size of a pointer (plus the&lt;br /&gt;
	 * size of the &amp;quot;sz&amp;quot; field, but we don't need to account for&lt;br /&gt;
	 * this), otherwise we could not possibly fit a freelist entry&lt;br /&gt;
	 * into the chunk later.&lt;br /&gt;
	 */&lt;br /&gt;
	if (len &amp;lt; sizeof(struct __freelist) - sizeof(size_t))&lt;br /&gt;
		len = sizeof(struct __freelist) - sizeof(size_t);&lt;br /&gt;
&lt;br /&gt;
	/*&lt;br /&gt;
	 * First, walk the free list and try finding a chunk that&lt;br /&gt;
	 * would match exactly.  If we found one, we are done.  While&lt;br /&gt;
	 * walking, note down the smallest chunk we found that would&lt;br /&gt;
	 * still fit the request -- we need it for step 2.&lt;br /&gt;
	 *&lt;br /&gt;
	 */&lt;br /&gt;
	for (s = 0, fp1 = __flp, fp2 = 0;&lt;br /&gt;
	     fp1;&lt;br /&gt;
	     fp2 = fp1, fp1 = fp1-&amp;gt;nx) {&lt;br /&gt;
		if (fp1-&amp;gt;sz &amp;lt; len)&lt;br /&gt;
			continue;&lt;br /&gt;
		if (fp1-&amp;gt;sz == len) {&lt;br /&gt;
			/*&lt;br /&gt;
			 * Found it.  Disconnect the chunk from the&lt;br /&gt;
			 * freelist, and return it.&lt;br /&gt;
			 */&lt;br /&gt;
			if (fp2)&lt;br /&gt;
				fp2-&amp;gt;nx = fp1-&amp;gt;nx;&lt;br /&gt;
			else&lt;br /&gt;
				__flp = fp1-&amp;gt;nx;&lt;br /&gt;
			return &amp;amp;(fp1-&amp;gt;nx);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			if (s == 0 || fp1-&amp;gt;sz &amp;lt; s) {&lt;br /&gt;
				/* this is the smallest chunk found so far */&lt;br /&gt;
				s = fp1-&amp;gt;sz;&lt;br /&gt;
				sfp1 = fp1;&lt;br /&gt;
				sfp2 = fp2;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	/*&lt;br /&gt;
	 * Step 2: If we found a chunk on the freelist that would fit&lt;br /&gt;
	 * (but was too large), look it up again and use it, since it&lt;br /&gt;
	 * is our closest match now.  Since the freelist entry needs&lt;br /&gt;
	 * to be split into two entries then, watch out that the&lt;br /&gt;
	 * difference between the requested size and the size of the&lt;br /&gt;
	 * chunk found is large enough for another freelist entry; if&lt;br /&gt;
	 * not, just enlarge the request size to what we have found,&lt;br /&gt;
	 * and use the entire chunk.&lt;br /&gt;
	 */&lt;br /&gt;
	if (s) {&lt;br /&gt;
		if (s - len &amp;lt; sizeof(struct __freelist)) {&lt;br /&gt;
			/* Disconnect it from freelist and return it. */&lt;br /&gt;
			if (sfp2)&lt;br /&gt;
				sfp2-&amp;gt;nx = sfp1-&amp;gt;nx;&lt;br /&gt;
			else&lt;br /&gt;
				__flp = sfp1-&amp;gt;nx;&lt;br /&gt;
			return &amp;amp;(sfp1-&amp;gt;nx);&lt;br /&gt;
		}&lt;br /&gt;
		/*&lt;br /&gt;
		 * Split them up.  Note that we leave the first part&lt;br /&gt;
		 * as the new (smaller) freelist entry, and return the&lt;br /&gt;
		 * upper portion to the caller.  This saves us the&lt;br /&gt;
		 * work to fix up the freelist chain; we just need to&lt;br /&gt;
		 * fixup the size of the current entry, and note down&lt;br /&gt;
		 * the size of the new chunk before returning it to&lt;br /&gt;
		 * the caller.&lt;br /&gt;
		 */&lt;br /&gt;
		cp = (char *)sfp1;&lt;br /&gt;
		s -= len;&lt;br /&gt;
		cp += s;&lt;br /&gt;
		sfp2 = (struct __freelist *)cp;&lt;br /&gt;
		sfp2-&amp;gt;sz = len;&lt;br /&gt;
		sfp1-&amp;gt;sz = s - sizeof(size_t);&lt;br /&gt;
		return &amp;amp;(sfp2-&amp;gt;nx);&lt;br /&gt;
	}&lt;br /&gt;
	/*&lt;br /&gt;
	 * Step 3: If the request could not be satisfied from a&lt;br /&gt;
	 * freelist entry, just prepare a new chunk.  This means we&lt;br /&gt;
	 * need to obtain more memory first.  The largest address just&lt;br /&gt;
	 * not allocated so far is remembered in the brkval variable.&lt;br /&gt;
	 * Under Unix, the &amp;quot;break value&amp;quot; was the end of the data&lt;br /&gt;
	 * segment as dynamically requested from the operating system.&lt;br /&gt;
	 * Since we don't have an operating system, just make sure&lt;br /&gt;
	 * that we don't collide with the stack.&lt;br /&gt;
	 */&lt;br /&gt;
	if (__brkval == 0)&lt;br /&gt;
		__brkval = __malloc_heap_start;&lt;br /&gt;
	cp = __malloc_heap_end;&lt;br /&gt;
	if (cp == 0)&lt;br /&gt;
		cp = STACK_POINTER() - __malloc_margin;&lt;br /&gt;
	if (cp &amp;lt;= __brkval)&lt;br /&gt;
	  /*&lt;br /&gt;
	   * Memory exhausted.&lt;br /&gt;
	   */&lt;br /&gt;
	  return 0;&lt;br /&gt;
	avail = cp - __brkval;&lt;br /&gt;
	/*&lt;br /&gt;
	 * Both tests below are needed to catch the case len &amp;gt;= 0xfffe.&lt;br /&gt;
	 */&lt;br /&gt;
	if (avail &amp;gt;= len &amp;amp;&amp;amp; avail &amp;gt;= len + sizeof(size_t)) {&lt;br /&gt;
		fp1 = (struct __freelist *)__brkval;&lt;br /&gt;
		__brkval += len + sizeof(size_t);&lt;br /&gt;
		fp1-&amp;gt;sz = len;&lt;br /&gt;
		return &amp;amp;(fp1-&amp;gt;nx);&lt;br /&gt;
	}&lt;br /&gt;
	/*&lt;br /&gt;
	 * Step 4: There's no help, just fail. :-/&lt;br /&gt;
	 */&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ATTRIBUTE_CLIB_SECTION&lt;br /&gt;
void&lt;br /&gt;
free(void *p)&lt;br /&gt;
{&lt;br /&gt;
	struct __freelist *fp1, *fp2, *fpnew;&lt;br /&gt;
	char *cp1, *cp2, *cpnew;&lt;br /&gt;
&lt;br /&gt;
	/* ISO C says free(NULL) must be a no-op */&lt;br /&gt;
	if (p == 0)&lt;br /&gt;
		return;&lt;br /&gt;
&lt;br /&gt;
	cpnew = p;&lt;br /&gt;
	cpnew -= sizeof(size_t);&lt;br /&gt;
	fpnew = (struct __freelist *)cpnew;&lt;br /&gt;
	fpnew-&amp;gt;nx = 0;&lt;br /&gt;
&lt;br /&gt;
	/*&lt;br /&gt;
	 * Trivial case first: if there's no freelist yet, our entry&lt;br /&gt;
	 * will be the only one on it.  If this is the last entry, we&lt;br /&gt;
	 * can reduce __brkval instead.&lt;br /&gt;
	 */&lt;br /&gt;
	if (__flp == 0) {&lt;br /&gt;
		if ((char *)p + fpnew-&amp;gt;sz == __brkval)&lt;br /&gt;
			__brkval = cpnew;&lt;br /&gt;
		else&lt;br /&gt;
			__flp = fpnew;&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/*&lt;br /&gt;
	 * Now, find the position where our new entry belongs onto the&lt;br /&gt;
	 * freelist.  Try to aggregate the chunk with adjacent chunks&lt;br /&gt;
	 * if possible.&lt;br /&gt;
	 */&lt;br /&gt;
	for (fp1 = __flp, fp2 = 0;&lt;br /&gt;
	     fp1;&lt;br /&gt;
	     fp2 = fp1, fp1 = fp1-&amp;gt;nx) {&lt;br /&gt;
		if (fp1 &amp;lt; fpnew)&lt;br /&gt;
			continue;&lt;br /&gt;
		cp1 = (char *)fp1;&lt;br /&gt;
		fpnew-&amp;gt;nx = fp1;&lt;br /&gt;
		if ((char *)&amp;amp;(fpnew-&amp;gt;nx) + fpnew-&amp;gt;sz == cp1) {&lt;br /&gt;
			/* upper chunk adjacent, assimilate it */&lt;br /&gt;
			fpnew-&amp;gt;sz += fp1-&amp;gt;sz + sizeof(size_t);&lt;br /&gt;
			fpnew-&amp;gt;nx = fp1-&amp;gt;nx;&lt;br /&gt;
		}&lt;br /&gt;
		if (fp2 == 0) {&lt;br /&gt;
			/* new head of freelist */&lt;br /&gt;
			__flp = fpnew;&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
	/*&lt;br /&gt;
	 * Note that we get here either if we hit the &amp;quot;break&amp;quot; above,&lt;br /&gt;
	 * or if we fell off the end of the loop.  The latter means&lt;br /&gt;
	 * we've got a new topmost chunk.  Either way, try aggregating&lt;br /&gt;
	 * with the lower chunk if possible.&lt;br /&gt;
	 */&lt;br /&gt;
	fp2-&amp;gt;nx = fpnew;&lt;br /&gt;
	cp2 = (char *)&amp;amp;(fp2-&amp;gt;nx);&lt;br /&gt;
	if (cp2 + fp2-&amp;gt;sz == cpnew) {&lt;br /&gt;
		/* lower junk adjacent, merge */&lt;br /&gt;
		fp2-&amp;gt;sz += fpnew-&amp;gt;sz + sizeof(size_t);&lt;br /&gt;
		fp2-&amp;gt;nx = fpnew-&amp;gt;nx;&lt;br /&gt;
	}&lt;br /&gt;
	/*&lt;br /&gt;
	 * If there's a new topmost chunk, lower __brkval instead.&lt;br /&gt;
	 */&lt;br /&gt;
	for (fp1 = __flp, fp2 = 0;&lt;br /&gt;
	     fp1-&amp;gt;nx != 0;&lt;br /&gt;
	     fp2 = fp1, fp1 = fp1-&amp;gt;nx)&lt;br /&gt;
		/* advance to entry just before end of list */;&lt;br /&gt;
	cp2 = (char *)&amp;amp;(fp1-&amp;gt;nx);&lt;br /&gt;
	if (cp2 + fp1-&amp;gt;sz == __brkval) {&lt;br /&gt;
		if (fp2 == NULL)&lt;br /&gt;
			/* Freelist is empty now. */&lt;br /&gt;
			__flp = NULL;&lt;br /&gt;
		else&lt;br /&gt;
			fp2-&amp;gt;nx = NULL;&lt;br /&gt;
		__brkval = cp2 - sizeof(size_t);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>YWrobot WM</name></author>	</entry>

	</feed>