Browse Source

remove soft timer tick increase

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2108 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 13 years ago
parent
commit
b14044212b
3 changed files with 350 additions and 335 deletions
  1. 1 2
      src/clock.c
  2. 296 296
      src/memheap.c
  3. 53 37
      src/timer.c

+ 1 - 2
src/clock.c

@@ -59,10 +59,9 @@ rt_tick_t rt_tick_get(void)
 void rt_tick_set(rt_tick_t tick)
 {
 	rt_base_t level;
-	level = rt_hw_interrupt_disable();
 
+	level = rt_hw_interrupt_disable();
 	rt_tick = tick;
-	
 	rt_hw_interrupt_enable(level);
 }
 

+ 296 - 296
src/memheap.c

@@ -1,296 +1,296 @@
-/*
- * File      : memheap.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2012, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2012-04-10     Bernard      first implementation
- */
-#include <rtthread.h>
-
-#ifdef RT_USING_MEMHEAP
-
-/* dynamic pool magic and mask */
-#define RT_MEMHEAP_MAGIC		0x1ea01ea0
-#define RT_MEMHEAP_MASK		0xfffffffe
-#define RT_MEMHEAP_USED		0x01
-#define RT_MEMHEAP_FREED		0x00
-
-#define RT_MEMHEAP_IS_USED(i)	((i)->magic & RT_MEMHEAP_USED)
-#define RT_MEMHEAP_MINIALLOC	12
-
-#define RT_MEMHEAP_SIZE		RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
-
-/*
- * The initialized memory pool will be:
- * +-----------------------------------+--------------------------+
- * | whole freed memory block          | Used Memory Block Tailer |
- * +-----------------------------------+--------------------------+
- *
- * block_list --> whole freed memory block
- *
- * The length of Used Memory Block Tailer is 0, which is prevents block merging across list
- */
-rt_err_t rt_memheap_init(struct rt_memheap* memheap, const char* name,
-	void *start_addr,
-	rt_uint32_t size)
-{
-	struct rt_memheap_item *item;
-
-	RT_ASSERT(memheap != RT_NULL);
-
-	/* initialize pool object */
-	rt_object_init(&(memheap->parent), RT_Object_Class_MemHeap, name);
-
-	memheap->start_addr = start_addr;
-	memheap->pool_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
-    memheap->available_size = memheap->pool_size - (2 * RT_MEMHEAP_SIZE);
-
-	/* initialize the free list header */
-	item = &(memheap->free_header);
-    item->magic = RT_MEMHEAP_MAGIC;
-    item->pool_ptr = memheap;
-    item->next = RT_NULL;
-    item->prev = RT_NULL;
-    item->next_free = item;
-    item->prev_free = item;
-
-	/* set the free list to free list header */
-	memheap->free_list = item;
-
-	/* initialize the first big memory block */
-	item = (struct rt_memheap_item*) start_addr;
-    item->magic = RT_MEMHEAP_MAGIC;
-    item->pool_ptr = memheap;
-    item->next = RT_NULL;
-    item->prev = RT_NULL;
-    item->next_free = item;
-    item->prev_free = item;
-
-    item->next = (struct rt_memheap_item *)
-           ((rt_uint8_t*) item + memheap->available_size + RT_MEMHEAP_SIZE);
-    item->prev =  item->next;
-
-	/* block list header */
-	memheap->block_list = item;
-
-	/* place the big memory block to free list */
-	item->next_free = memheap->free_list->next_free;
-	item->prev_free = memheap->free_list;
-	memheap->free_list->next_free->prev_free = item;
-	memheap->free_list->next_free = item;
-
-	/* move to the end of memory pool to build a small tailer block, which prevents block merging */
-    item =  item->next;
-	/* it's a used memory block */
-    item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED;
-    item->pool_ptr = memheap;
-    item->next = (struct rt_memheap_item *) start_addr;
-    item->prev = (struct rt_memheap_item *) start_addr;
-	/* not in free list */
-    item->next_free = item->prev_free = RT_NULL;
-
-    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x",
-    		start_addr,	size, &(memheap->free_header)));
-
-    return RT_EOK;
-}
-
-rt_err_t rt_memheap_detach(struct rt_memheap* heap)
-{
-	rt_object_detach(&(heap->parent));
-
-    /* Return a successful completion.  */
-    return RT_EOK;
-}
-
-void* rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
-{
-	rt_uint32_t free_size;
-	struct rt_memheap_item *header_ptr;
-
-	RT_ASSERT(pool_ptr != RT_NULL);
-
-	/* align allocated size */
-	size = RT_ALIGN(size, RT_ALIGN_SIZE);
-	if (size < RT_MEMHEAP_MINIALLOC) size = RT_MEMHEAP_MINIALLOC;
-
-	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size));
-
-	if (size < pool_ptr->available_size)
-	{
-		/* search on free list */
-		free_size = 0;
-		/* get the first free memory block */
-		header_ptr = pool_ptr->free_list->next_free;
-		while (header_ptr != pool_ptr->free_list && free_size < size)
-		{
-			/* get current freed memory block size */
-			free_size = (rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr - RT_MEMHEAP_SIZE;
-
-			if (free_size < size)
-			{
-				/* move to next free memory block */
-				header_ptr = header_ptr->next_free;
-			}
-		}
-
-		/* determine if the memory is available.  */
-		if (free_size >= size)
-		{
-			/* a block that satisfies the request has been found.  */
-
-			/* determine if the block needs to be split.  */
-			if (free_size >= (size + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC))
-			{
-				struct rt_memheap_item* new_ptr;
-
-				/* split the block.  */
-				new_ptr =  (struct rt_memheap_item*) (((rt_uint8_t*) header_ptr) + size + RT_MEMHEAP_SIZE);
-
-				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("split: h[0x%08x] nm[0x%08x] pm[0x%08x] to n[0x%08x]", header_ptr,
-					header_ptr->next, header_ptr->prev,
-					new_ptr));
-
-				/* mark the new block as a memory block and freed. */
-				new_ptr->magic = RT_MEMHEAP_MAGIC;
-
-				/* put the pool pointer into the new block.  */
-				new_ptr->pool_ptr = pool_ptr;
-
-				/* break down the block list */
-				new_ptr->prev = header_ptr;
-				new_ptr->next = header_ptr->next;
-				header_ptr->next->prev = new_ptr;
-				header_ptr->next = new_ptr;
-
-				/* remove header ptr from free list */
-				header_ptr->next_free->prev_free = header_ptr->prev_free;
-				header_ptr->prev_free->next_free = header_ptr->next_free;
-				header_ptr->next_free = RT_NULL;
-				header_ptr->prev_free = RT_NULL;
-
-				/* insert new_ptr to free list */
-				new_ptr->next_free = pool_ptr->free_list->next_free;
-				new_ptr->prev_free = pool_ptr->free_list;
-				pool_ptr->free_list->next_free->prev_free = new_ptr;
-				pool_ptr->free_list->next_free = new_ptr;
-				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: nf 0x%08x, pf 0x%08x",
-						new_ptr->next_free, new_ptr->prev_free));
-
-				/* decrement the available byte count.  */
-				pool_ptr->available_size = pool_ptr->available_size - size - RT_MEMHEAP_SIZE;
-			}
-			else
-			{
-				/* decrement the entire free size from the available bytes count.  */
-				pool_ptr->available_size =  pool_ptr->available_size - free_size;
-
-				/* remove header_ptr from free list */
-				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("one block: h[0x%08x], nf 0x%08x, pf 0x%08x", header_ptr,
-					header_ptr->next_free, header_ptr->prev_free));
-
-				header_ptr->next_free->prev_free = header_ptr->prev_free;
-				header_ptr->prev_free->next_free = header_ptr->next_free;
-				header_ptr->next_free = RT_NULL;
-				header_ptr->prev_free = RT_NULL;
-			}
-
-			/* Mark the allocated block as not available.  */
-			header_ptr->magic |=  RT_MEMHEAP_USED;
-
-			/* Return a memory address to the caller.  */
-			RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("am: m[0x%08x], h[0x%08x], size: %d",
-					(void*) ((rt_uint8_t*)header_ptr + RT_MEMHEAP_SIZE), header_ptr, size);
-			return (void*) ((rt_uint8_t*)header_ptr + RT_MEMHEAP_SIZE));
-		}
-	}
-
-	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n"));
-
-    /* Return the completion status.  */
-    return RT_NULL;
-}
-
-void rt_memheap_free(void* ptr)
-{
-	struct rt_memheap *pool_ptr;
-	struct rt_memheap_item *header_ptr, *new_ptr;
-	rt_uint32_t insert_header;
-
-	/* set initial status as OK */
-	insert_header = 1; new_ptr = RT_NULL;
-	header_ptr = (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE);
-
-	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: m[0x%08x], h[0x%08x]", ptr, header_ptr));
-
-	/* check magic */
-	RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
-
-	/* get pool ptr */
-	pool_ptr = header_ptr->pool_ptr;
-
-    /* Mark the memory as available.  */
-    header_ptr->magic &= ~RT_MEMHEAP_USED;
-
-    /* Adjust the available number of bytes.  */
-    pool_ptr->available_size =  pool_ptr->available_size +
-                        ((rt_uint32_t)(header_ptr->next) -
-                        (rt_uint32_t)header_ptr) - RT_MEMHEAP_SIZE;
-
-    /* Determine if the block can be merged with the previous neighbor.  */
-    if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
-    {
-    	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x", header_ptr->prev));
-
-        /* adjust the available number of bytes.  */
-        pool_ptr->available_size =  pool_ptr->available_size + RT_MEMHEAP_SIZE;
-
-        /* yes, merge block with previous neighbor.  */
-        (header_ptr->prev)->next = header_ptr->next;
-        (header_ptr->next)->prev = header_ptr->prev;
-
-        /* move header pointer to previous.  */
-        header_ptr = header_ptr->prev;
-		insert_header = 0;	/* don't insert header to free list */
-    }
-
-    /* determine if the block can be merged with the next neighbor.  */
-    if (!RT_MEMHEAP_IS_USED(header_ptr->next))
-    {
-        /* adjust the available number of bytes.  */
-        pool_ptr->available_size =  pool_ptr->available_size + RT_MEMHEAP_SIZE;
-
-        /* merge block with next neighbor.  */
-        new_ptr =  header_ptr->next;
-
-        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: right node 0x%08x, nf 0x%08x, pf 0x%08x",
-        		new_ptr, new_ptr->next_free, new_ptr->prev_free));
-
-        new_ptr->next->prev = header_ptr;
-        header_ptr->next = new_ptr->next;
-
-		/* remove new ptr from free list */
-		new_ptr->next_free->prev_free = new_ptr->prev_free;
-		new_ptr->prev_free->next_free = new_ptr->next_free;
-    }
-
-	if (insert_header)
-	{
-		/* no left merge, insert to free list */
-		header_ptr->next_free = pool_ptr->free_list->next_free;
-		header_ptr->prev_free = pool_ptr->free_list;
-		pool_ptr->free_list->next_free->prev_free = header_ptr;
-		pool_ptr->free_list->next_free = header_ptr;
-
-		RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("insert to free list: nf 0x%08x, pf 0x%08x",
-				header_ptr->next_free, header_ptr->prev_free));
-	}
-}
-
-#endif
+/*
+ * File      : memheap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-04-10     Bernard      first implementation
+ */
+#include <rtthread.h>
+
+#ifdef RT_USING_MEMHEAP
+
+/* dynamic pool magic and mask */
+#define RT_MEMHEAP_MAGIC		0x1ea01ea0
+#define RT_MEMHEAP_MASK		0xfffffffe
+#define RT_MEMHEAP_USED		0x01
+#define RT_MEMHEAP_FREED		0x00
+
+#define RT_MEMHEAP_IS_USED(i)	((i)->magic & RT_MEMHEAP_USED)
+#define RT_MEMHEAP_MINIALLOC	12
+
+#define RT_MEMHEAP_SIZE		RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
+
+/*
+ * The initialized memory pool will be:
+ * +-----------------------------------+--------------------------+
+ * | whole freed memory block          | Used Memory Block Tailer |
+ * +-----------------------------------+--------------------------+
+ *
+ * block_list --> whole freed memory block
+ *
+ * The length of Used Memory Block Tailer is 0, which is prevents block merging across list
+ */
+rt_err_t rt_memheap_init(struct rt_memheap* memheap, const char* name,
+	void *start_addr,
+	rt_uint32_t size)
+{
+	struct rt_memheap_item *item;
+
+	RT_ASSERT(memheap != RT_NULL);
+
+	/* initialize pool object */
+	rt_object_init(&(memheap->parent), RT_Object_Class_MemHeap, name);
+
+	memheap->start_addr = start_addr;
+	memheap->pool_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
+    memheap->available_size = memheap->pool_size - (2 * RT_MEMHEAP_SIZE);
+
+	/* initialize the free list header */
+	item = &(memheap->free_header);
+    item->magic = RT_MEMHEAP_MAGIC;
+    item->pool_ptr = memheap;
+    item->next = RT_NULL;
+    item->prev = RT_NULL;
+    item->next_free = item;
+    item->prev_free = item;
+
+	/* set the free list to free list header */
+	memheap->free_list = item;
+
+	/* initialize the first big memory block */
+	item = (struct rt_memheap_item*) start_addr;
+    item->magic = RT_MEMHEAP_MAGIC;
+    item->pool_ptr = memheap;
+    item->next = RT_NULL;
+    item->prev = RT_NULL;
+    item->next_free = item;
+    item->prev_free = item;
+
+    item->next = (struct rt_memheap_item *)
+           ((rt_uint8_t*) item + memheap->available_size + RT_MEMHEAP_SIZE);
+    item->prev =  item->next;
+
+	/* block list header */
+	memheap->block_list = item;
+
+	/* place the big memory block to free list */
+	item->next_free = memheap->free_list->next_free;
+	item->prev_free = memheap->free_list;
+	memheap->free_list->next_free->prev_free = item;
+	memheap->free_list->next_free = item;
+
+	/* move to the end of memory pool to build a small tailer block, which prevents block merging */
+    item =  item->next;
+	/* it's a used memory block */
+    item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED;
+    item->pool_ptr = memheap;
+    item->next = (struct rt_memheap_item *) start_addr;
+    item->prev = (struct rt_memheap_item *) start_addr;
+	/* not in free list */
+    item->next_free = item->prev_free = RT_NULL;
+
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x",
+    		start_addr,	size, &(memheap->free_header)));
+
+    return RT_EOK;
+}
+
+rt_err_t rt_memheap_detach(struct rt_memheap* heap)
+{
+	rt_object_detach(&(heap->parent));
+
+    /* Return a successful completion.  */
+    return RT_EOK;
+}
+
+void* rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
+{
+	rt_uint32_t free_size;
+	struct rt_memheap_item *header_ptr;
+
+	RT_ASSERT(pool_ptr != RT_NULL);
+
+	/* align allocated size */
+	size = RT_ALIGN(size, RT_ALIGN_SIZE);
+	if (size < RT_MEMHEAP_MINIALLOC) size = RT_MEMHEAP_MINIALLOC;
+
+	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size));
+
+	if (size < pool_ptr->available_size)
+	{
+		/* search on free list */
+		free_size = 0;
+		/* get the first free memory block */
+		header_ptr = pool_ptr->free_list->next_free;
+		while (header_ptr != pool_ptr->free_list && free_size < size)
+		{
+			/* get current freed memory block size */
+			free_size = (rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr - RT_MEMHEAP_SIZE;
+
+			if (free_size < size)
+			{
+				/* move to next free memory block */
+				header_ptr = header_ptr->next_free;
+			}
+		}
+
+		/* determine if the memory is available.  */
+		if (free_size >= size)
+		{
+			/* a block that satisfies the request has been found.  */
+
+			/* determine if the block needs to be split.  */
+			if (free_size >= (size + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC))
+			{
+				struct rt_memheap_item* new_ptr;
+
+				/* split the block.  */
+				new_ptr =  (struct rt_memheap_item*) (((rt_uint8_t*) header_ptr) + size + RT_MEMHEAP_SIZE);
+
+				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("split: h[0x%08x] nm[0x%08x] pm[0x%08x] to n[0x%08x]", header_ptr,
+					header_ptr->next, header_ptr->prev,
+					new_ptr));
+
+				/* mark the new block as a memory block and freed. */
+				new_ptr->magic = RT_MEMHEAP_MAGIC;
+
+				/* put the pool pointer into the new block.  */
+				new_ptr->pool_ptr = pool_ptr;
+
+				/* break down the block list */
+				new_ptr->prev = header_ptr;
+				new_ptr->next = header_ptr->next;
+				header_ptr->next->prev = new_ptr;
+				header_ptr->next = new_ptr;
+
+				/* remove header ptr from free list */
+				header_ptr->next_free->prev_free = header_ptr->prev_free;
+				header_ptr->prev_free->next_free = header_ptr->next_free;
+				header_ptr->next_free = RT_NULL;
+				header_ptr->prev_free = RT_NULL;
+
+				/* insert new_ptr to free list */
+				new_ptr->next_free = pool_ptr->free_list->next_free;
+				new_ptr->prev_free = pool_ptr->free_list;
+				pool_ptr->free_list->next_free->prev_free = new_ptr;
+				pool_ptr->free_list->next_free = new_ptr;
+				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: nf 0x%08x, pf 0x%08x",
+						new_ptr->next_free, new_ptr->prev_free));
+
+				/* decrement the available byte count.  */
+				pool_ptr->available_size = pool_ptr->available_size - size - RT_MEMHEAP_SIZE;
+			}
+			else
+			{
+				/* decrement the entire free size from the available bytes count.  */
+				pool_ptr->available_size =  pool_ptr->available_size - free_size;
+
+				/* remove header_ptr from free list */
+				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("one block: h[0x%08x], nf 0x%08x, pf 0x%08x", header_ptr,
+					header_ptr->next_free, header_ptr->prev_free));
+
+				header_ptr->next_free->prev_free = header_ptr->prev_free;
+				header_ptr->prev_free->next_free = header_ptr->next_free;
+				header_ptr->next_free = RT_NULL;
+				header_ptr->prev_free = RT_NULL;
+			}
+
+			/* Mark the allocated block as not available.  */
+			header_ptr->magic |=  RT_MEMHEAP_USED;
+
+			/* Return a memory address to the caller.  */
+			RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("am: m[0x%08x], h[0x%08x], size: %d",
+					(void*) ((rt_uint8_t*)header_ptr + RT_MEMHEAP_SIZE), header_ptr, size);
+			return (void*) ((rt_uint8_t*)header_ptr + RT_MEMHEAP_SIZE));
+		}
+	}
+
+	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n"));
+
+    /* Return the completion status.  */
+    return RT_NULL;
+}
+
+void rt_memheap_free(void* ptr)
+{
+	struct rt_memheap *pool_ptr;
+	struct rt_memheap_item *header_ptr, *new_ptr;
+	rt_uint32_t insert_header;
+
+	/* set initial status as OK */
+	insert_header = 1; new_ptr = RT_NULL;
+	header_ptr = (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE);
+
+	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: m[0x%08x], h[0x%08x]", ptr, header_ptr));
+
+	/* check magic */
+	RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
+
+	/* get pool ptr */
+	pool_ptr = header_ptr->pool_ptr;
+
+    /* Mark the memory as available.  */
+    header_ptr->magic &= ~RT_MEMHEAP_USED;
+
+    /* Adjust the available number of bytes.  */
+    pool_ptr->available_size =  pool_ptr->available_size +
+                        ((rt_uint32_t)(header_ptr->next) -
+                        (rt_uint32_t)header_ptr) - RT_MEMHEAP_SIZE;
+
+    /* Determine if the block can be merged with the previous neighbor.  */
+    if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
+    {
+    	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x", header_ptr->prev));
+
+        /* adjust the available number of bytes.  */
+        pool_ptr->available_size =  pool_ptr->available_size + RT_MEMHEAP_SIZE;
+
+        /* yes, merge block with previous neighbor.  */
+        (header_ptr->prev)->next = header_ptr->next;
+        (header_ptr->next)->prev = header_ptr->prev;
+
+        /* move header pointer to previous.  */
+        header_ptr = header_ptr->prev;
+		insert_header = 0;	/* don't insert header to free list */
+    }
+
+    /* determine if the block can be merged with the next neighbor.  */
+    if (!RT_MEMHEAP_IS_USED(header_ptr->next))
+    {
+        /* adjust the available number of bytes.  */
+        pool_ptr->available_size =  pool_ptr->available_size + RT_MEMHEAP_SIZE;
+
+        /* merge block with next neighbor.  */
+        new_ptr =  header_ptr->next;
+
+        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: right node 0x%08x, nf 0x%08x, pf 0x%08x",
+        		new_ptr, new_ptr->next_free, new_ptr->prev_free));
+
+        new_ptr->next->prev = header_ptr;
+        header_ptr->next = new_ptr->next;
+
+		/* remove new ptr from free list */
+		new_ptr->next_free->prev_free = new_ptr->prev_free;
+		new_ptr->prev_free->next_free = new_ptr->next_free;
+    }
+
+	if (insert_header)
+	{
+		/* no left merge, insert to free list */
+		header_ptr->next_free = pool_ptr->free_list->next_free;
+		header_ptr->prev_free = pool_ptr->free_list;
+		pool_ptr->free_list->next_free->prev_free = header_ptr;
+		pool_ptr->free_list->next_free = header_ptr;
+
+		RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("insert to free list: nf 0x%08x, pf 0x%08x",
+				header_ptr->next_free, header_ptr->prev_free));
+	}
+}
+
+#endif

+ 53 - 37
src/timer.c

@@ -28,6 +28,9 @@ static rt_list_t rt_timer_list = RT_LIST_OBJECT_INIT(rt_timer_list);
 #ifdef RT_USING_TIMER_SOFT
 /* soft timer list */
 static rt_list_t rt_soft_timer_list;
+static struct rt_thread timer_thread;
+ALIGN(RT_ALIGN_SIZE)
+static rt_uint8_t timer_thread_stack[RT_TIMER_THREAD_STACK_SIZE];
 #endif
 
 #ifdef RT_USING_HOOK
@@ -75,6 +78,15 @@ static void _rt_timer_init(rt_timer_t timer,
 	rt_list_init(&(timer->list));
 }
 
+static rt_tick_t rt_timer_list_next_timeout(rt_list_t* timer_list)
+{
+	struct rt_timer* timer;
+	if (rt_list_isempty(timer_list)) return RT_TICK_MAX;
+	
+	timer = rt_list_entry(timer_list->next, struct rt_timer, list);
+	return timer->timeout_tick;
+}
+
 /**
  * @addtogroup Clock
  */
@@ -211,13 +223,13 @@ rt_err_t rt_timer_start(rt_timer_t timer)
 
 	RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
 
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
-
 	/* get timeout tick, the max timeout tick shall not great than RT_TICK_MAX/2 */
 	RT_ASSERT(timer->init_tick < RT_TICK_MAX/2);
 	timer->timeout_tick = rt_tick_get() + timer->init_tick;
 
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
 #ifdef RT_USING_TIMER_SOFT
 	if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
 	{
@@ -249,12 +261,25 @@ rt_err_t rt_timer_start(rt_timer_t timer)
 	{
 		rt_list_insert_before(n, &(timer->list));
 	}
-		
+
 	timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;
 
 	/* enable interrupt */
 	rt_hw_interrupt_enable(level);
 
+#ifdef RT_USING_TIMER_SOFT
+	if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
+	{
+		/* check whether timer thread is ready */
+		if (timer_thread.stat != RT_THREAD_READY)
+		{
+			/* resume timer thread to check soft timer */
+			rt_thread_resume(&timer_thread);
+			rt_schedule();
+		}
+	}
+#endif
+
 	return -RT_EOK;
 }
 
@@ -279,15 +304,15 @@ rt_err_t rt_timer_stop(rt_timer_t timer)
 	/* disable interrupt */
 	level = rt_hw_interrupt_disable();
 
-	/* change stat */
-	timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
-
 	/* remove it from timer list */
 	rt_list_remove(&(timer->list));
 
 	/* enable interrupt */
 	rt_hw_interrupt_enable(level);
 
+	/* change stat */
+	timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+
 	return RT_EOK;
 }
 
@@ -333,9 +358,6 @@ rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg)
  *
  * @note this function shall be invoked in operating system timer interrupt.
  */
-#ifdef RT_USING_TIMER_SOFT
-void rt_soft_timer_tick_increase(void);
-#endif
 void rt_timer_check(void)
 {
 	struct rt_timer *t;
@@ -391,32 +413,20 @@ void rt_timer_check(void)
 	/* enable interrupt */
 	rt_hw_interrupt_enable(level);
 
-	/* increase soft timer tick */
-#ifdef RT_USING_TIMER_SOFT
-	rt_soft_timer_tick_increase();
-#endif
-
 	RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check leave\n"));
 }
 
-#ifdef RT_USING_TIMER_SOFT
-static struct rt_thread timer_thread;
-ALIGN(RT_ALIGN_SIZE)
-static rt_uint8_t timer_thread_stack[RT_TIMER_THREAD_STACK_SIZE];
-static struct rt_semaphore timer_sem;
-
-static rt_uint16_t timer_ex_cnt;
-
-void rt_soft_timer_tick_increase(void)
+/**
+ * This function will return the next timeout tick in the system.
+ *
+ * @return the next timeout tick in the system
+ */
+rt_tick_t rt_timer_next_timeout_tick(void)
 {
-	timer_ex_cnt ++;
-	if (timer_ex_cnt >= (RT_TICK_PER_SECOND / RT_TIMER_TICK_PER_SECOND))
-	{
-		timer_ex_cnt = 0;
-		rt_sem_release(&timer_sem);
-	}
+	return rt_timer_list_next_timeout(&rt_timer_list);
 }
 
+#ifdef RT_USING_TIMER_SOFT
 /**
  * This function will check timer list, if a timeout event happens, the
  * corresponding timeout function will be invoked.
@@ -469,8 +479,7 @@ void rt_soft_timer_check(void)
 				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
 			}
 		}
-		else
-			break; /* not check anymore */
+		else break; /* not check anymore */
 	}
 
 	RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
@@ -479,17 +488,25 @@ void rt_soft_timer_check(void)
 /* system timer thread entry */
 static void rt_thread_timer_entry(void *parameter)
 {
+	rt_tick_t next_timeout;
+	
 	while (1)
 	{
-		/* take software timer semaphore */
-		rt_sem_take(&timer_sem, RT_WAITING_FOREVER);
+		next_timeout = rt_timer_list_next_timeout(&rt_soft_timer_list);
+		if (next_timeout == RT_TICK_MAX)
+		{
+			rt_thread_suspend(rt_thread_self());
+			rt_schedule();
+		}
+		else
+		{
+			rt_thread_delay(next_timeout);
+		}
 
 		/* lock scheduler */
 		rt_enter_critical();
-
 		/* check software timer */
 		rt_soft_timer_check();
-
 		/* unlock scheduler */
 		rt_exit_critical();
 	}
@@ -517,7 +534,6 @@ void rt_system_timer_thread_init(void)
 {
 #ifdef RT_USING_TIMER_SOFT
 	rt_list_init(&rt_soft_timer_list);
-	rt_sem_init(&timer_sem, "timer", 0, RT_IPC_FLAG_FIFO);
 
 	/* start software timer thread */
 	rt_thread_init(&timer_thread,