summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsheltonyu <[email protected]>2021-04-13 11:37:46 +0800
committerGitHub <[email protected]>2021-04-13 11:37:46 +0800
commit46c5ba9225702bf473646ec2f4200c9560e2db90 (patch)
treea7fe59ac9ce9a6a1c90d9c81324a4a6bb91b38a4 /src
parent35ef1f9e0fcf1ae881a83558dbf7334ab08c598e (diff)
parentc44e5165bef5b7b069eb99a4f027454f417a726b (diff)
Merge branch 'master' into developer
Diffstat (limited to 'src')
-rw-r--r--src/Kconfig38
-rw-r--r--src/clock.c4
-rw-r--r--src/components.c2
-rw-r--r--src/cpu.c2
-rw-r--r--src/device.c16
-rw-r--r--src/idle.c4
-rwxr-xr-xsrc/ipc.c22
-rw-r--r--src/irq.c6
-rw-r--r--src/kservice.c43
-rw-r--r--src/mem.c4
-rw-r--r--src/memheap.c310
-rw-r--r--src/mempool.c2
-rw-r--r--src/object.c10
-rw-r--r--src/scheduler.c8
-rw-r--r--src/signal.c2
-rw-r--r--src/slab.c2
-rw-r--r--src/thread.c167
-rw-r--r--src/timer.c8
18 files changed, 455 insertions, 195 deletions
diff --git a/src/Kconfig b/src/Kconfig
index 803c827e51..6afb719395 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -116,6 +116,18 @@ config RT_TIMER_THREAD_STACK_SIZE
endif
+menu "kservice optimization"
+
+config RT_KSERVICE_USING_STDLIB
+ bool "Enable kservice to use standard C library"
+ default n
+
+config RT_KSERVICE_USING_TINY_SIZE
+ bool "Enable kservice to use tiny size"
+ default n
+
+endmenu
+
menuconfig RT_DEBUG
bool "Enable debugging features"
default y
@@ -284,21 +296,19 @@ menu "Memory Management"
endchoice
- if RT_USING_SMALL_MEM
- config RT_USING_MEMTRACE
- bool "Enable memory trace"
- default n
- help
- When enable RT_USING_MEMTRACE with shell, developer can call cmd:
- 1. memtrace
- to dump memory block information.
- 2. memcheck
- to check memory block to avoid memory overwritten.
+ config RT_USING_MEMTRACE
+ bool "Enable memory trace"
+ default n
+ help
+ When enable RT_USING_MEMTRACE with shell, developer can call cmd:
+ 1. memtrace
+ to dump memory block information.
+ 2. memcheck
+ to check memory block to avoid memory overwritten.
- And developer also can call memcheck() in each of scheduling
- to check memory block to find which thread has wrongly modified
- memory.
- endif
+ And developer also can call memcheck() in each of scheduling
+ to check memory block to find which thread has wrongly modified
+ memory.
config RT_USING_HEAP
bool
diff --git a/src/clock.c b/src/clock.c
index 66923e5c00..0880d8d241 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -111,7 +111,7 @@ rt_tick_t rt_tick_from_millisecond(rt_int32_t ms)
tick = RT_TICK_PER_SECOND * (ms / 1000);
tick += (RT_TICK_PER_SECOND * (ms % 1000) + 999) / 1000;
}
-
+
/* return the calculated tick */
return tick;
}
diff --git a/src/components.c b/src/components.c
index 8ea5654d0c..9709d0aae2 100644
--- a/src/components.c
+++ b/src/components.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
diff --git a/src/cpu.c b/src/cpu.c
index 96e585713b..48ddb12c46 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
diff --git a/src/device.c b/src/device.c
index a4f004fb69..50b83c7692 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -12,6 +12,7 @@
* 2012-12-25 Bernard return RT_EOK if the device interface not exist.
* 2013-07-09 Grissiom add ref_count support
* 2016-04-02 Bernard fix the open_flag initialization issue.
+ * 2021-03-19 Meco Man remove rt_device_init_all()
*/
#include <rtthread.h>
@@ -90,19 +91,6 @@ rt_err_t rt_device_unregister(rt_device_t dev)
RTM_EXPORT(rt_device_unregister);
/**
- * This function initializes all registered device driver
- *
- * @return the error code, RT_EOK on successfully.
- *
- * @deprecated since 1.2.x, this function is not needed because the initialization
- * of a device is performed when application opens it.
- */
-rt_err_t rt_device_init_all(void)
-{
- return RT_EOK;
-}
-
-/**
* This function finds a device driver by specified name.
*
* @param name the device driver's name
diff --git a/src/idle.c b/src/idle.c
index aa14552a49..24dfffbc6d 100644
--- a/src/idle.c
+++ b/src/idle.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -211,7 +211,7 @@ static void rt_thread_idle_entry(void *parameter)
#endif
rt_thread_idle_excute();
-#ifdef RT_USING_PM
+#ifdef RT_USING_PM
rt_system_power_manager();
#endif
}
diff --git a/src/ipc.c b/src/ipc.c
index d037708979..111d724c23 100755
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -34,7 +34,7 @@
* 2013-09-14 Grissiom add an option check in rt_event_recv
* 2018-10-02 Bernard add 64bit support for mailbox
* 2019-09-16 tyx add send wait support for message queue
- * 2020-07-29 Meco Man fix thread->event_set/event_info when received an
+ * 2020-07-29 Meco Man fix thread->event_set/event_info when received an
* event without pending
* 2020-10-11 Meco Man add value overflow-check code
* 2021-01-03 Meco Man add rt_mb_urgent()
@@ -124,7 +124,7 @@ rt_inline rt_err_t rt_ipc_list_suspend(rt_list_t *list,
break;
default:
- break;
+ break;
}
return RT_EOK;
@@ -959,7 +959,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
rt_hw_interrupt_enable(temp); /* enable interrupt */
return -RT_EFULL; /* value overflowed */
}
-
+
/* clear owner */
mutex->owner = RT_NULL;
mutex->original_priority = 0xff;
@@ -1280,11 +1280,11 @@ rt_err_t rt_event_recv(rt_event_t event,
/* set received event */
if (recved)
*recved = (event->set & set);
-
- /* fill thread event info */
+
+ /* fill thread event info */
thread->event_set = (event->set & set);
thread->event_info = option;
-
+
/* received event */
if (option & RT_EVENT_FLAG_CLEAR)
event->set &= ~set;
@@ -1649,7 +1649,7 @@ rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
++ mb->in_offset;
if (mb->in_offset >= mb->size)
mb->in_offset = 0;
-
+
if(mb->entry < RT_MB_ENTRY_MAX)
{
/* increase message entry */
@@ -1660,7 +1660,7 @@ rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
rt_hw_interrupt_enable(temp); /* enable interrupt */
return -RT_EFULL; /* value overflowed */
}
-
+
/* resume suspended thread */
if (!rt_list_isempty(&mb->parent.suspend_thread))
{
@@ -2203,7 +2203,7 @@ rt_err_t rt_mq_send_wait(rt_mq_t mq,
}
/* message queue is full */
- while ((msg = mq->msg_queue_free) == RT_NULL)
+ while ((msg = (struct rt_mq_message *)mq->msg_queue_free) == RT_NULL)
{
/* reset error number in thread */
thread->error = RT_EOK;
@@ -2409,7 +2409,7 @@ rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)
rt_hw_interrupt_enable(temp); /* enable interrupt */
return -RT_EFULL; /* value overflowed */
}
-
+
/* resume suspended thread */
if (!rt_list_isempty(&mq->parent.suspend_thread))
{
diff --git a/src/irq.c b/src/irq.c
index 311d297bfe..177c1a9ff5 100644
--- a/src/irq.c
+++ b/src/irq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -21,7 +21,7 @@ static void (*rt_interrupt_leave_hook)(void);
/**
* @ingroup Hook
- * This function set a hook function when the system enter a interrupt
+ * This function set a hook function when the system enter a interrupt
*
* @note the hook function must be simple and never be blocked or suspend.
*/
@@ -31,7 +31,7 @@ void rt_interrupt_enter_sethook(void (*hook)(void))
}
/**
* @ingroup Hook
- * This function set a hook function when the system exit a interrupt.
+ * This function set a hook function when the system exit a interrupt.
*
* @note the hook function must be simple and never be blocked or suspend.
*/
diff --git a/src/kservice.c b/src/kservice.c
index 423fe3ddb3..e9972dba97 100644
--- a/src/kservice.c
+++ b/src/kservice.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -17,6 +17,7 @@
* 2013-06-24 Bernard remove rt_kprintf if RT_USING_CONSOLE is not defined.
* 2013-09-24 aozima make sure the device is in STREAM mode when used by rt_kprintf.
* 2015-07-06 Bernard Add rt_assert_handler routine.
+ * 2021-02-28 Meco Man add RT_KSERVICE_USING_STDLIB
*/
#include <rtthread.h>
@@ -125,7 +126,7 @@ RTM_EXPORT(_rt_errno);
*/
RT_WEAK void *rt_memset(void *s, int c, rt_ubase_t count)
{
-#ifdef RT_USING_TINY_SIZE
+#ifdef RT_KSERVICE_USING_TINY_SIZE
char *xs = (char *)s;
while (count--)
@@ -146,10 +147,10 @@ RT_WEAK void *rt_memset(void *s, int c, rt_ubase_t count)
if (!TOO_SMALL(count) && !UNALIGNED(s))
{
- /* If we get this far, we know that n is large and m is word-aligned. */
+ /* If we get this far, we know that count is large and s is word-aligned. */
aligned_addr = (unsigned long *)s;
- /* Store D into each char sized location in BUFFER so that
+ /* Store d into each char sized location in buffer so that
* we can set large blocks quickly.
*/
if (LBLOCKSIZE == 4)
@@ -209,7 +210,7 @@ RTM_EXPORT(rt_memset);
*/
RT_WEAK void *rt_memcpy(void *dst, const void *src, rt_ubase_t count)
{
-#ifdef RT_USING_TINY_SIZE
+#ifdef RT_KSERVICE_USING_TINY_SIZE
char *tmp = (char *)dst, *s = (char *)src;
rt_ubase_t len;
@@ -280,6 +281,8 @@ RT_WEAK void *rt_memcpy(void *dst, const void *src, rt_ubase_t count)
}
RTM_EXPORT(rt_memcpy);
+#ifndef RT_KSERVICE_USING_STDLIB
+
/**
* This function will move memory content from source address to destination
* address.
@@ -456,7 +459,7 @@ RTM_EXPORT(rt_strncmp);
rt_int32_t rt_strcmp(const char *cs, const char *ct)
{
while (*cs && *cs == *ct)
- {
+ {
cs++;
ct++;
}
@@ -506,6 +509,8 @@ rt_size_t rt_strlen(const char *s)
}
RTM_EXPORT(rt_strlen);
+#endif /*RT_KSERVICE_USING_STDLIB*/
+
#ifdef RT_USING_HEAP
/**
* This function will duplicate a string.
@@ -1127,10 +1132,10 @@ rt_device_t rt_console_set_device(const char *name)
/* find new console device */
new_device = rt_device_find(name);
-
+
/* check whether it's a same device */
if (new_device == old_device) return RT_NULL;
-
+
if (new_device != RT_NULL)
{
if (_console_device != RT_NULL)
@@ -1386,26 +1391,4 @@ void rt_assert_handler(const char *ex_string, const char *func, rt_size_t line)
RTM_EXPORT(rt_assert_handler);
#endif /* RT_DEBUG */
-#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) && defined (__GNUC__)
-#include <sys/types.h>
-void *memcpy(void *dest, const void *src, size_t n) __attribute__((weak, alias("rt_memcpy")));
-void *memset(void *s, int c, size_t n) __attribute__((weak, alias("rt_memset")));
-void *memmove(void *dest, const void *src, size_t n) __attribute__((weak, alias("rt_memmove")));
-int memcmp(const void *s1, const void *s2, size_t n) __attribute__((weak, alias("rt_memcmp")));
-
-size_t strlen(const char *s) __attribute__((weak, alias("rt_strlen")));
-char *strstr(const char *s1, const char *s2) __attribute__((weak, alias("rt_strstr")));
-int strcasecmp(const char *a, const char *b) __attribute__((weak, alias("rt_strcasecmp")));
-char *strncpy(char *dest, const char *src, size_t n) __attribute__((weak, alias("rt_strncpy")));
-int strncmp(const char *cs, const char *ct, size_t count) __attribute__((weak, alias("rt_strncmp")));
-#ifdef RT_USING_HEAP
-char *strdup(const char *s) __attribute__((weak, alias("rt_strdup")));
-#endif
-
-int sprintf(char *buf, const char *format, ...) __attribute__((weak, alias("rt_sprintf")));
-int snprintf(char *buf, rt_size_t size, const char *fmt, ...) __attribute__((weak, alias("rt_snprintf")));
-int vsprintf(char *buf, const char *format, va_list arg_ptr) __attribute__((weak, alias("rt_vsprintf")));
-
-#endif
-
/**@}*/
diff --git a/src/mem.c b/src/mem.c
index c03c8b3452..ac0d27f2c3 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -489,7 +489,7 @@ void *rt_realloc(void *rmem, rt_size_t newsize)
{
((struct heap_mem *)&heap_ptr[mem2->next])->prev = ptr2;
}
-
+
if (mem2 < lfree)
{
/* the splited struct is now the lowest */
diff --git a/src/memheap.c b/src/memheap.c
index afa06fb9bf..63327575cc 100644
--- a/src/memheap.c
+++ b/src/memheap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -35,6 +35,45 @@
#define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
#define MEMITEM_SIZE(item) ((rt_ubase_t)item->next - (rt_ubase_t)item - RT_MEMHEAP_SIZE)
+#define MEMITEM(ptr) (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE)
+
+#ifdef RT_USING_MEMTRACE
+rt_inline void rt_memheap_setname(struct rt_memheap_item *item, const char *name)
+{
+ int index;
+ rt_uint8_t* ptr;
+
+ ptr = (rt_uint8_t*)&(item->next_free);
+ for (index = 0; index < sizeof(void*); index ++)
+ {
+ if (name[index] == '\0') break;
+ ptr[index] = name[index];
+ }
+ if (name[index] == '\0') ptr[index] = '\0';
+ else
+ {
+ ptr = (rt_uint8_t*)&(item->prev_free);
+ for (index = 0; index < sizeof(void*) && (index + sizeof(void*))< RT_NAME_MAX; index ++)
+ {
+ if (name[sizeof(void*) + index] == '\0') break;
+ ptr[index] = name[sizeof(void*) + index];
+ }
+
+ if (name[sizeof(void*) + index] == '\0') ptr[index] = '\0';
+ }
+}
+
+void rt_mem_set_tag(void* ptr, const char* name)
+{
+ struct rt_memheap_item* item;
+
+ if (ptr && name)
+ {
+ item = MEMITEM(ptr);
+ rt_memheap_setname(item, name);
+ }
+}
+#endif
/*
* The initialized memory pool will be:
@@ -66,7 +105,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
/* initialize the free list header */
item = &(memheap->free_header);
- item->magic = RT_MEMHEAP_MAGIC;
+ item->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
item->pool_ptr = memheap;
item->next = RT_NULL;
item->prev = RT_NULL;
@@ -78,13 +117,17 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
/* initialize the first big memory block */
item = (struct rt_memheap_item *)start_addr;
- item->magic = RT_MEMHEAP_MAGIC;
+ item->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
item->pool_ptr = memheap;
item->next = RT_NULL;
item->prev = RT_NULL;
item->next_free = item;
item->prev_free = item;
+#ifdef RT_USING_MEMTRACE
+ rt_memset(item->owner_thread_name, ' ', sizeof(item->owner_thread_name));
+#endif
+
item->next = (struct rt_memheap_item *)
((rt_uint8_t *)item + memheap->available_size + RT_MEMHEAP_SIZE);
item->prev = item->next;
@@ -103,7 +146,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
*/
item = item->next;
/* it's a used memory block */
- item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED;
+ 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;
@@ -126,7 +169,7 @@ rt_err_t rt_memheap_detach(struct rt_memheap *heap)
RT_ASSERT(heap);
RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
RT_ASSERT(rt_object_is_systemobject(&heap->parent));
-
+
rt_sem_detach(&heap->lock);
rt_object_detach(&(heap->parent));
@@ -201,11 +244,15 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
new_ptr));
/* mark the new block as a memory block and freed. */
- new_ptr->magic = RT_MEMHEAP_MAGIC;
+ new_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
/* put the pool pointer into the new block. */
new_ptr->pool_ptr = heap;
+#ifdef RT_USING_MEMTRACE
+ rt_memset(new_ptr->owner_thread_name, ' ', sizeof(new_ptr->owner_thread_name));
+#endif
+
/* break down the block list */
new_ptr->prev = header_ptr;
new_ptr->next = header_ptr->next;
@@ -255,7 +302,14 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size)
}
/* Mark the allocated block as not available. */
- header_ptr->magic |= RT_MEMHEAP_USED;
+ header_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED);
+
+#ifdef RT_USING_MEMTRACE
+ if (rt_thread_self())
+ rt_memcpy(header_ptr->owner_thread_name, rt_thread_self()->name, sizeof(header_ptr->owner_thread_name));
+ else
+ rt_memcpy(header_ptr->owner_thread_name, "NONE", sizeof(header_ptr->owner_thread_name));
+#endif
/* release lock */
rt_sem_release(&(heap->lock));
@@ -376,11 +430,15 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
next_ptr->prev));
/* mark the new block as a memory block and freed. */
- next_ptr->magic = RT_MEMHEAP_MAGIC;
+ next_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
/* put the pool pointer into the new block. */
next_ptr->pool_ptr = heap;
+#ifdef RT_USING_MEMTRACE
+ rt_memset(next_ptr->owner_thread_name, ' ', sizeof(next_ptr->owner_thread_name));
+#endif
+
next_ptr->prev = header_ptr;
next_ptr->next = header_ptr->next;
header_ptr->next->prev = next_ptr;
@@ -441,10 +499,14 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
new_ptr));
/* mark the new block as a memory block and freed. */
- new_ptr->magic = RT_MEMHEAP_MAGIC;
+ new_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
/* put the pool pointer into the new block. */
new_ptr->pool_ptr = heap;
+#ifdef RT_USING_MEMTRACE
+ rt_memset(new_ptr->owner_thread_name, ' ', sizeof(new_ptr->owner_thread_name));
+#endif
+
/* break down the block list */
new_ptr->prev = header_ptr;
new_ptr->next = header_ptr->next;
@@ -512,8 +574,12 @@ void rt_memheap_free(void *ptr)
ptr, header_ptr));
/* check magic */
- RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
- RT_ASSERT(header_ptr->magic & RT_MEMHEAP_USED);
+ if (header_ptr->magic != (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED))
+ {
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("bad magic:0x%08x @ memheap\n",
+ header_ptr->magic));
+ }
+ RT_ASSERT(header_ptr->magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED));
/* check whether this block of memory has been over-written. */
RT_ASSERT((header_ptr->next->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
@@ -533,9 +599,9 @@ void rt_memheap_free(void *ptr)
}
/* Mark the memory as available. */
- header_ptr->magic &= ~RT_MEMHEAP_USED;
+ header_ptr->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED);
/* Adjust the available number of bytes. */
- heap->available_size = heap->available_size + MEMITEM_SIZE(header_ptr);
+ heap->available_size += MEMITEM_SIZE(header_ptr);
/* Determine if the block can be merged with the previous neighbor. */
if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
@@ -544,7 +610,7 @@ void rt_memheap_free(void *ptr)
header_ptr->prev));
/* adjust the available number of bytes. */
- heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
+ heap->available_size += RT_MEMHEAP_SIZE;
/* yes, merge block with previous neighbor. */
(header_ptr->prev)->next = header_ptr->next;
@@ -560,7 +626,7 @@ void rt_memheap_free(void *ptr)
if (!RT_MEMHEAP_IS_USED(header_ptr->next))
{
/* adjust the available number of bytes. */
- heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
+ heap->available_size += RT_MEMHEAP_SIZE;
/* merge block with next neighbor. */
new_ptr = header_ptr->next;
@@ -590,11 +656,100 @@ void rt_memheap_free(void *ptr)
header_ptr->next_free, header_ptr->prev_free));
}
+#ifdef RT_USING_MEMTRACE
+ rt_memset(header_ptr->owner_thread_name, ' ', sizeof(header_ptr->owner_thread_name));
+#endif
+
/* release lock */
rt_sem_release(&(heap->lock));
}
RTM_EXPORT(rt_memheap_free);
+#ifdef RT_USING_FINSH
+static void _memheap_dump_tag(struct rt_memheap_item* item)
+{
+ rt_uint8_t name[2 * sizeof(void*)];
+ rt_uint8_t* ptr;
+
+ ptr = (rt_uint8_t*)&(item->next_free);
+ rt_memcpy(name, ptr, sizeof(void*));
+ ptr = (rt_uint8_t*)&(item->prev_free);
+ rt_memcpy(&name[sizeof(void*)], ptr, sizeof(void*));
+
+ rt_kprintf("%.*s", 2 * sizeof(void*), name);
+}
+
+int rt_memheap_dump(struct rt_memheap *heap)
+{
+ struct rt_memheap_item *item, *end;
+
+ if (heap == RT_NULL) return 0;
+ RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap);
+
+ rt_kprintf("\n[%.*s] [0x%08x - 0x%08x]->\n", RT_NAME_MAX, heap->parent.name,
+ (rt_ubase_t)heap->start_addr, (rt_ubase_t)heap->start_addr + heap->pool_size);
+ rt_kprintf("------------------------------\n");
+
+ /* lock memheap */
+ rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
+ item = heap->block_list;
+
+ end = (struct rt_memheap_item *) ((rt_uint8_t *)heap->start_addr + heap->pool_size - RT_MEMHEAP_SIZE);
+
+ /* for each memory block */
+ while ((rt_ubase_t)item < ((rt_ubase_t)end))
+ {
+ if (RT_MEMHEAP_IS_USED(item) && ((item->magic & RT_MEMHEAP_MASK) != RT_MEMHEAP_MAGIC))
+ rt_kprintf("0x%08x", item + 1);
+
+ if (item->magic == (RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED))
+ {
+ rt_kprintf("0x%08x: %-8d ", item + 1, MEMITEM_SIZE(item));
+ _memheap_dump_tag(item);
+ rt_kprintf("\n");
+ }
+ else
+ {
+ rt_kprintf("0x%08x: %-8d <F>\n", item + 1, MEMITEM_SIZE(item));
+ }
+
+ item = item->next;
+ }
+ rt_sem_release(&(heap->lock));
+
+ return 0;
+}
+
+int memheaptrace(void)
+{
+ int count = rt_object_get_length(RT_Object_Class_MemHeap);
+ struct rt_memheap **heaps;
+
+ if (count > 0)
+ {
+ int index;
+ extern int list_memheap(void);
+
+ heaps = (struct rt_memheap**)rt_malloc(sizeof(struct rt_memheap*) * count);
+ if (heaps == RT_NULL) return 0;
+
+ list_memheap();
+
+ rt_kprintf("memheap header size: %d\n", RT_MEMHEAP_SIZE);
+ count = rt_object_get_pointers(RT_Object_Class_MemHeap, (rt_object_t*)heaps, count);
+ for (index = 0; index < count; index++)
+ {
+ rt_memheap_dump(heaps[index]);
+ }
+
+ rt_free(heaps);
+ }
+
+ return 0;
+}
+MSH_CMD_EXPORT(memheaptrace, dump memory trace information);
+#endif
+
#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap _heap;
@@ -643,6 +798,24 @@ void *rt_malloc(rt_size_t size)
}
}
+
+#ifdef RT_USING_MEMTRACE
+ if (ptr == RT_NULL)
+ {
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("malloc[%d] => NULL", size));
+ }
+ else
+ {
+ struct rt_memheap_item *item = MEMITEM(ptr);
+ if (rt_thread_self())
+ rt_memheap_setname(item, rt_thread_self()->name);
+ else
+ rt_memheap_setname(item, "<null>");
+
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("malloc => 0x%08x : %d", ptr, size));
+ }
+#endif
+
return ptr;
}
RTM_EXPORT(rt_malloc);
@@ -691,6 +864,24 @@ void *rt_realloc(void *rmem, rt_size_t newsize)
}
}
+#ifdef RT_USING_MEMTRACE
+ if (new_ptr == RT_NULL)
+ {
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("realloc[%d] => NULL", newsize));
+ }
+ else
+ {
+ struct rt_memheap_item *item = MEMITEM(new_ptr);
+ if (rt_thread_self())
+ rt_memheap_setname(item, rt_thread_self()->name);
+ else
+ rt_memheap_setname(item, "<null>");
+
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("realloc => 0x%08x : %d",
+ new_ptr, newsize));
+ }
+#endif
+
return new_ptr;
}
RTM_EXPORT(rt_realloc);
@@ -708,6 +899,19 @@ void *rt_calloc(rt_size_t count, rt_size_t size)
rt_memset(ptr, 0, total_size);
}
+#ifdef RT_USING_MEMTRACE
+ if (ptr == RT_NULL)
+ {
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("calloc[%d x %d] => NULL",
+ count, size));
+ }
+ else
+ {
+ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("calloc => 0x%08x : %d",
+ ptr, count * size));
+ }
+#endif
+
return ptr;
}
RTM_EXPORT(rt_calloc);
@@ -728,4 +932,78 @@ void rt_memory_info(rt_uint32_t *total,
#endif
-#endif
+#ifdef RT_USING_MEMTRACE
+
+void dump_used_memheap(struct rt_memheap *mh)
+{
+ struct rt_memheap_item *header_ptr;
+ rt_uint32_t block_size;
+
+
+ rt_kprintf("\nmemory heap address:\n");
+ rt_kprintf("heap_ptr: 0x%08x\n", mh->start_addr);
+ rt_kprintf("free : 0x%08x\n", mh->available_size);
+ rt_kprintf("max_used: 0x%08x\n", mh->max_used_size);
+ rt_kprintf("size : 0x%08x\n", mh->pool_size);
+
+ rt_kprintf("\n--memory used information --\n");
+
+ header_ptr = mh->block_list;
+ while (header_ptr->next != mh->block_list)
+ {
+ if ((header_ptr->magic & RT_MEMHEAP_MASK) != RT_MEMHEAP_MAGIC)
+ {
+ rt_kprintf("[0x%08x - incorrect magic: 0x%08x\n", header_ptr, header_ptr->magic);
+ break;
+ }
+
+ /* get current memory block size */
+ block_size = MEMITEM_SIZE(header_ptr);
+ if (block_size < 0)
+ break;
+
+ if (RT_MEMHEAP_IS_USED(header_ptr))
+ {
+ /* dump information */
+ rt_kprintf("[0x%08x - %d - %c%c%c%c] used\n", header_ptr, block_size,
+ header_ptr->owner_thread_name[0], header_ptr->owner_thread_name[1],
+ header_ptr->owner_thread_name[2], header_ptr->owner_thread_name[3]);
+ }
+ else
+ {
+ /* dump information */
+ rt_kprintf("[0x%08x - %d - %c%c%c%c] free\n", header_ptr, block_size,
+ header_ptr->owner_thread_name[0], header_ptr->owner_thread_name[1],
+ header_ptr->owner_thread_name[2], header_ptr->owner_thread_name[3]);
+ }
+
+ /* move to next used memory block */
+ header_ptr = header_ptr->next;
+ }
+}
+
+void memtrace_heap()
+{
+ struct rt_object_information *info;
+ struct rt_list_node *list;
+ struct rt_memheap *mh;
+ struct rt_list_node *node;
+
+ info = rt_object_get_information(RT_Object_Class_MemHeap);
+ list = &info->object_list;
+
+ for (node = list->next; node != list; node = node->next)
+ {
+ mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);
+ dump_used_memheap(mh);
+ }
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+MSH_CMD_EXPORT(memtrace_heap, dump memory trace for heap);
+#endif /* end of RT_USING_FINSH */
+
+#endif /* end of RT_USING_MEMTRACE */
+
+#endif /* end of RT_USING_MEMHEAP */
diff --git a/src/mempool.c b/src/mempool.c
index db614032aa..1de48940d7 100644
--- a/src/mempool.c
+++ b/src/mempool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
diff --git a/src/object.c b/src/object.c
index 56263618b3..013e2d1e33 100644
--- a/src/object.c
+++ b/src/object.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -200,7 +200,7 @@ void rt_object_put_sethook(void (*hook)(struct rt_object *object))
/**
* This function will return the specified type of object information.
*
- * @param type the type of object, which can be
+ * @param type the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
*
* @return the object type information or RT_NULL
@@ -220,7 +220,7 @@ RTM_EXPORT(rt_object_get_information);
/**
* This function will return the length of object list in object container.
*
- * @param type the type of object, which can be
+ * @param type the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
* @return the length of object list
*/
@@ -247,10 +247,10 @@ int rt_object_get_length(enum rt_object_class_type type)
RTM_EXPORT(rt_object_get_length);
/**
- * This function will copy the object pointer of the specified type,
+ * This function will copy the object pointer of the specified type,
* with the maximum size specified by maxlen.
*
- * @param type the type of object, which can be
+ * @param type the type of object, which can be
* RT_Object_Class_Thread/Semaphore/Mutex... etc
* @param pointers the pointers will be saved to
* @param maxlen the maximum number of pointers can be saved
diff --git a/src/scheduler.c b/src/scheduler.c
index 06f305ea0b..c03c20d030 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -270,10 +270,10 @@ void rt_system_scheduler_start(void)
#ifdef RT_USING_SMP
/**
* This function will handle IPI interrupt and do a scheduling in system;
- *
+ *
* @param vector, the number of IPI interrupt for system scheduling
* @param param, use RT_NULL
- *
+ *
* NOTE: this function should be invoke or register as ISR in BSP.
*/
void rt_scheduler_ipi_handler(int vector, void *param)
@@ -283,7 +283,7 @@ void rt_scheduler_ipi_handler(int vector, void *param)
/**
* This function will perform one scheduling. It will select one thread
- * with the highest priority level in global ready queue or local ready queue,
+ * with the highest priority level in global ready queue or local ready queue,
* then switch to it.
*/
void rt_schedule(void)
diff --git a/src/signal.c b/src/signal.c
index bb9339ab6c..c2c3e975cb 100644
--- a/src/signal.c
+++ b/src/signal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
diff --git a/src/slab.c b/src/slab.c
index 0872ecf092..12ca1a938c 100644
--- a/src/slab.c
+++ b/src/slab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
diff --git a/src/thread.c b/src/thread.c
index 0db9dd8e4d..34e96077d1 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -26,6 +26,7 @@
* bug when thread has not startup.
* 2018-11-22 Jesven yield is same to rt_schedule
* add support for tasks bound to cpu
+ * 2021-02-24 Meco Man rearrange rt_thread_control() - schedule the thread when close it
*/
#include <rthw.h>
@@ -357,8 +358,6 @@ RTM_EXPORT(rt_thread_startup);
*/
rt_err_t rt_thread_detach(rt_thread_t thread)
{
- rt_base_t lock;
-
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
@@ -381,19 +380,8 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
/* change stat */
thread->stat = RT_THREAD_CLOSE;
- if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
- {
- rt_object_detach((rt_object_t)thread);
- }
- else
- {
- /* disable interrupt */
- lock = rt_hw_interrupt_disable();
- /* insert to defunct thread list */
- rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
- /* enable interrupt */
- rt_hw_interrupt_enable(lock);
- }
+ /* detach thread object */
+ rt_object_detach((rt_object_t)thread);
return RT_EOK;
}
@@ -585,6 +573,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick)
{
register rt_base_t level;
struct rt_thread *thread;
+ rt_tick_t cur_tick;
RT_ASSERT(tick != RT_NULL);
@@ -596,15 +585,19 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick)
/* disable interrupt */
level = rt_hw_interrupt_disable();
- if (rt_tick_get() - *tick < inc_tick)
+ cur_tick = rt_tick_get();
+ if (cur_tick - *tick < inc_tick)
{
- *tick = *tick + inc_tick - rt_tick_get();
+ rt_tick_t left_tick;
+
+ *tick += inc_tick;
+ left_tick = *tick - cur_tick;
/* suspend thread */
rt_thread_suspend(thread);
/* reset the timeout of thread timer and start it */
- rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, tick);
+ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &left_tick);
rt_timer_start(&(thread->thread_timer));
/* enable interrupt */
@@ -620,12 +613,10 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick)
}
else
{
+ *tick = cur_tick;
rt_hw_interrupt_enable(level);
}
- /* get the wakeup tick */
- *tick = rt_tick_get();
-
return RT_EOK;
}
RTM_EXPORT(rt_thread_delay_until);
@@ -670,83 +661,93 @@ rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
switch (cmd)
{
- case RT_THREAD_CTRL_CHANGE_PRIORITY:
- /* disable interrupt */
- temp = rt_hw_interrupt_disable();
-
- /* for ready thread, change queue */
- if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY)
+ case RT_THREAD_CTRL_CHANGE_PRIORITY:
{
- /* remove thread from schedule queue first */
- rt_schedule_remove_thread(thread);
+ /* disable interrupt */
+ temp = rt_hw_interrupt_disable();
- /* change thread priority */
- thread->current_priority = *(rt_uint8_t *)arg;
-
- /* recalculate priority attribute */
-#if RT_THREAD_PRIORITY_MAX > 32
- thread->number = thread->current_priority >> 3; /* 5bit */
- thread->number_mask = 1 << thread->number;
- thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
-#else
- thread->number_mask = 1 << thread->current_priority;
-#endif
+ /* for ready thread, change queue */
+ if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY)
+ {
+ /* remove thread from schedule queue first */
+ rt_schedule_remove_thread(thread);
- /* insert thread to schedule queue again */
- rt_schedule_insert_thread(thread);
- }
- else
- {
- thread->current_priority = *(rt_uint8_t *)arg;
+ /* change thread priority */
+ thread->current_priority = *(rt_uint8_t *)arg;
- /* recalculate priority attribute */
-#if RT_THREAD_PRIORITY_MAX > 32
- thread->number = thread->current_priority >> 3; /* 5bit */
- thread->number_mask = 1 << thread->number;
- thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
-#else
- thread->number_mask = 1 << thread->current_priority;
-#endif
- }
+ /* recalculate priority attribute */
+ #if RT_THREAD_PRIORITY_MAX > 32
+ thread->number = thread->current_priority >> 3; /* 5bit */
+ thread->number_mask = 1 << thread->number;
+ thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
+ #else
+ thread->number_mask = 1 << thread->current_priority;
+ #endif
- /* enable interrupt */
- rt_hw_interrupt_enable(temp);
- break;
+ /* insert thread to schedule queue again */
+ rt_schedule_insert_thread(thread);
+ }
+ else
+ {
+ thread->current_priority = *(rt_uint8_t *)arg;
- case RT_THREAD_CTRL_STARTUP:
- return rt_thread_startup(thread);
+ /* recalculate priority attribute */
+ #if RT_THREAD_PRIORITY_MAX > 32
+ thread->number = thread->current_priority >> 3; /* 5bit */
+ thread->number_mask = 1 << thread->number;
+ thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
+ #else
+ thread->number_mask = 1 << thread->current_priority;
+ #endif
+ }
- case RT_THREAD_CTRL_CLOSE:
+ /* enable interrupt */
+ rt_hw_interrupt_enable(temp);
+ break;
+ }
- if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
+ case RT_THREAD_CTRL_STARTUP:
{
- return rt_thread_detach(thread);
+ return rt_thread_startup(thread);
}
-#ifdef RT_USING_HEAP
- else
+
+ case RT_THREAD_CTRL_CLOSE:
{
- return rt_thread_delete(thread);
- }
-#endif
+ rt_err_t rt_err;
-#ifdef RT_USING_SMP
- case RT_THREAD_CTRL_BIND_CPU:
- {
- rt_uint8_t cpu;
+ if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
+ {
+ rt_err = rt_thread_detach(thread);
+ }
+ #ifdef RT_USING_HEAP
+ else
+ {
+ rt_err = rt_thread_delete(thread);
+ }
+ #endif
+ rt_schedule();
+ return rt_err;
+ }
- if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
+ #ifdef RT_USING_SMP
+ case RT_THREAD_CTRL_BIND_CPU:
{
- /* we only support bind cpu before started phase. */
- return RT_ERROR;
+ rt_uint8_t cpu;
+
+ if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
+ {
+ /* we only support bind cpu before started phase. */
+ return RT_ERROR;
+ }
+
+ cpu = (rt_uint8_t)(size_t)arg;
+ thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu;
+ break;
}
+ #endif /*RT_USING_SMP*/
- cpu = (rt_uint8_t)(size_t)arg;
- thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu;
- break;
- }
-#endif /*RT_USING_SMP*/
- default:
- break;
+ default:
+ break;
}
return RT_EOK;
diff --git a/src/timer.c b/src/timer.c
index d882711151..836df51e06 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -201,7 +201,7 @@ void rt_timer_init(rt_timer_t timer,
RT_ASSERT(timer != RT_NULL);
/* timer object initialization */
- rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
+ rt_object_init(&(timer->parent), RT_Object_Class_Timer, name);
_rt_timer_init(timer, timeout, parameter, time, flag);
}
@@ -233,7 +233,7 @@ rt_err_t rt_timer_detach(rt_timer_t timer)
/* enable interrupt */
rt_hw_interrupt_enable(level);
- rt_object_detach((rt_object_t)timer);
+ rt_object_detach(&(timer->parent));
return RT_EOK;
}
@@ -298,7 +298,7 @@ rt_err_t rt_timer_delete(rt_timer_t timer)
/* enable interrupt */
rt_hw_interrupt_enable(level);
- rt_object_delete((rt_object_t)timer);
+ rt_object_delete(&(timer->parent));
return RT_EOK;
}