diff options
| author | lizhirui <[email protected]> | 2021-05-18 09:54:11 +0800 |
|---|---|---|
| committer | lizhirui <[email protected]> | 2021-05-18 09:54:11 +0800 |
| commit | 9a4e270f9770f778128ffdabe94f101416ce8c61 (patch) | |
| tree | 9df43fbcc25c3f288ed6fdecd65909d4094d849f /src | |
| parent | e7fc0c89d2367533dcd1b77e46acaeea7bc3f876 (diff) | |
| parent | 4e9e3f79a565bb4fdc1d96deda18f9c771aeb0c9 (diff) | |
Merge branch 'RT-Thread:master' into master
Diffstat (limited to 'src')
| -rw-r--r-- | src/Kconfig | 40 | ||||
| -rw-r--r-- | src/clock.c | 4 | ||||
| -rw-r--r-- | src/components.c | 2 | ||||
| -rw-r--r-- | src/cpu.c | 2 | ||||
| -rw-r--r-- | src/device.c | 16 | ||||
| -rw-r--r-- | src/idle.c | 4 | ||||
| -rwxr-xr-x | src/ipc.c | 22 | ||||
| -rw-r--r-- | src/irq.c | 14 | ||||
| -rw-r--r-- | src/kservice.c | 45 | ||||
| -rw-r--r-- | src/mem.c | 4 | ||||
| -rw-r--r-- | src/memheap.c | 310 | ||||
| -rw-r--r-- | src/mempool.c | 2 | ||||
| -rw-r--r-- | src/object.c | 10 | ||||
| -rw-r--r-- | src/scheduler.c | 8 | ||||
| -rw-r--r-- | src/signal.c | 2 | ||||
| -rw-r--r-- | src/slab.c | 2 | ||||
| -rw-r--r-- | src/thread.c | 167 | ||||
| -rw-r--r-- | src/timer.c | 8 |
18 files changed, 461 insertions, 201 deletions
diff --git a/src/Kconfig b/src/Kconfig index 803c827e51..9a49146dff 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 @@ -343,7 +353,7 @@ endmenu config RT_VER_NUM hex - default 0x40003 + default 0x40004 help RT-Thread version number 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 * @@ -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 } @@ -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)) { @@ -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. */ @@ -66,13 +66,13 @@ void rt_interrupt_enter(void) { rt_base_t level; - RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq coming..., irq nest:%d\n", - rt_interrupt_nest)); - level = rt_hw_interrupt_disable(); rt_interrupt_nest ++; RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,()); rt_hw_interrupt_enable(level); + + RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq has come..., irq current nest:%d\n", + rt_interrupt_nest)); } RTM_EXPORT(rt_interrupt_enter); @@ -87,7 +87,7 @@ void rt_interrupt_leave(void) { rt_base_t level; - RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq leave, irq nest:%d\n", + RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq is going to leave, irq current nest:%d\n", rt_interrupt_nest)); level = rt_hw_interrupt_disable(); diff --git a/src/kservice.c b/src/kservice.c index 423fe3ddb3..7ed05b6651 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. @@ -917,7 +922,7 @@ rt_int32_t rt_vsnprintf(char *buf, s = va_arg(args, char *); if (!s) s = "(NULL)"; - len = rt_strlen(s); + for (len = 0; (len != field_width) && (s[len] != '\0'); len++); #ifdef RT_PRINTF_PRECISION if (precision > 0 && len > precision) len = precision; #endif @@ -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 - /**@}*/ @@ -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; } |
