1
0
Эх сурвалжийг харах

Merge pull request #4756 from Guozhanxin/ac6

[src][memheap]Fix the crash problem after opening Oz optimization on ac6.
Bernard Xiong 3 жил өмнө
parent
commit
52a66cc96f

+ 1 - 1
.github/workflows/action_utest.yml

@@ -11,7 +11,7 @@ jobs:
       fail-fast: false
       matrix:
        legs:
-         - {UTEST: "kernel/ipc",       RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"}
+         - {UTEST: "kernel/mem",       RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/kernel/config.h"}
          - {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"}
     
     env:

+ 304 - 0
examples/utest/configs/kernel/config.h

@@ -0,0 +1,304 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Project Configuration */
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+#define RT_USING_SMP
+#define RT_CPUS_NR 2
+#define RT_ALIGN_SIZE 4
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_USING_OVERFLOW_CHECK
+#define RT_USING_HOOK
+#define RT_USING_IDLE_HOOK
+#define RT_IDLE_HOOK_LIST_SIZE 4
+#define IDLE_THREAD_STACK_SIZE 1024
+#define RT_USING_TIMER_SOFT
+#define RT_TIMER_THREAD_PRIO 4
+#define RT_TIMER_THREAD_STACK_SIZE 1024
+
+/* kservice optimization */
+
+#define RT_DEBUG
+#define RT_DEBUG_COLOR
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+#define RT_USING_SIGNALS
+
+/* Memory Management */
+
+#define RT_USING_MEMPOOL
+#define RT_USING_MEMHEAP
+#define RT_USING_SMALL_MEM
+#define RT_USING_MEMTRACE
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+#define RT_USING_DEVICE_OPS
+#define RT_USING_INTERRUPT_INFO
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 256
+#define RT_CONSOLE_DEVICE_NAME "uart0"
+#define RT_VER_NUM 0x40004
+#define ARCH_ARM
+#define RT_USING_CPU_FFS
+#define ARCH_ARM_CORTEX_A
+#define RT_USING_GIC_V2
+#define ARCH_ARM_CORTEX_A9
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+#define RT_MAIN_THREAD_PRIORITY 10
+
+/* C++ features */
+
+#define RT_USING_CPLUSPLUS
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
+#define FINSH_CMD_SIZE 80
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_DEFAULT
+#define FINSH_ARG_MAX 10
+
+/* Device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_WORKDIR
+#define DFS_FILESYSTEMS_MAX 4
+#define DFS_FILESYSTEM_TYPES_MAX 8
+#define DFS_FD_MAX 32
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_3
+#define RT_DFS_ELM_USE_LFN 3
+#define RT_DFS_ELM_LFN_UNICODE_0
+#define RT_DFS_ELM_LFN_UNICODE 0
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
+#define RT_DFS_ELM_REENTRANT
+#define RT_USING_DFS_DEVFS
+#define RT_USING_DFS_ROMFS
+#define RT_USING_DFS_RAMFS
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_PIPE_BUFSZ 512
+#define RT_USING_SYSTEM_WORKQUEUE
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
+#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
+#define RT_USING_SERIAL
+#define RT_SERIAL_USING_DMA
+#define RT_SERIAL_RB_BUFSZ 64
+#define RT_USING_I2C
+#define RT_USING_I2C_BITOPS
+#define RT_USING_PIN
+#define RT_USING_MTD_NOR
+#define RT_USING_MTD_NAND
+#define RT_MTD_NAND_DEBUG
+#define RT_USING_RTC
+#define RT_USING_SOFT_RTC
+#define RT_USING_SDIO
+#define RT_SDIO_STACK_SIZE 512
+#define RT_SDIO_THREAD_PRIORITY 15
+#define RT_MMCSD_STACK_SIZE 1024
+#define RT_MMCSD_THREAD_PREORITY 22
+#define RT_MMCSD_MAX_PARTITION 16
+#define RT_USING_SPI
+#define RT_USING_SPI_MSD
+#define RT_USING_SFUD
+#define RT_SFUD_USING_SFDP
+#define RT_SFUD_USING_FLASH_INFO_TABLE
+#define RT_SFUD_SPI_MAX_HZ 50000000
+#define RT_USING_WDT
+
+/* Using USB */
+
+
+/* POSIX layer and C standard library */
+
+#define RT_USING_LIBC
+#define RT_USING_PTHREADS
+#define PTHREAD_NUM_MAX 8
+#define RT_USING_POSIX
+#define RT_USING_POSIX_MMAP
+#define RT_USING_POSIX_TERMIOS
+#define RT_USING_POSIX_GETLINE
+#define RT_USING_POSIX_AIO
+#define RT_LIBC_FIXED_TIMEZONE 8
+
+/* Network */
+
+/* Socket abstraction layer */
+
+#define RT_USING_SAL
+#define SAL_INTERNET_CHECK
+
+/* protocol stack implement */
+
+#define SAL_USING_LWIP
+#define SAL_USING_POSIX
+
+/* Network interface device */
+
+#define RT_USING_NETDEV
+#define NETDEV_USING_IFCONFIG
+#define NETDEV_USING_PING
+#define NETDEV_USING_NETSTAT
+#define NETDEV_USING_AUTO_DEFAULT
+#define NETDEV_IPV4 1
+#define NETDEV_IPV6 0
+
+/* light weight TCP/IP stack */
+
+#define RT_USING_LWIP
+#define RT_USING_LWIP202
+#define RT_LWIP_MEM_ALIGNMENT 4
+#define RT_LWIP_ICMP
+#define RT_LWIP_DNS
+#define RT_LWIP_DHCP
+#define IP_SOF_BROADCAST 1
+#define IP_SOF_BROADCAST_RECV 1
+
+/* Static IPv4 Address */
+
+#define RT_LWIP_IPADDR "192.168.1.30"
+#define RT_LWIP_GWADDR "192.168.1.1"
+#define RT_LWIP_MSKADDR "255.255.255.0"
+#define RT_LWIP_UDP
+#define RT_LWIP_TCP
+#define RT_LWIP_RAW
+#define RT_MEMP_NUM_NETCONN 8
+#define RT_LWIP_PBUF_NUM 16
+#define RT_LWIP_RAW_PCB_NUM 4
+#define RT_LWIP_UDP_PCB_NUM 4
+#define RT_LWIP_TCP_PCB_NUM 4
+#define RT_LWIP_TCP_SEG_NUM 40
+#define RT_LWIP_TCP_SND_BUF 8196
+#define RT_LWIP_TCP_WND 8196
+#define RT_LWIP_TCPTHREAD_PRIORITY 10
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
+#define RT_LWIP_TCPTHREAD_STACKSIZE 1024
+#define RT_LWIP_ETHTHREAD_PRIORITY 12
+#define RT_LWIP_ETHTHREAD_STACKSIZE 1024
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
+#define RT_LWIP_REASSEMBLY_FRAG
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define SO_REUSE 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_SNDTIMEO 1
+#define LWIP_SO_RCVBUF 1
+#define LWIP_SO_LINGER 0
+#define LWIP_NETIF_LOOPBACK 0
+#define RT_LWIP_USING_PING
+
+/* AT commands */
+
+
+/* VBUS(Virtual Software BUS) */
+
+
+/* Utilities */
+
+#define RT_USING_UTEST
+#define UTEST_THR_STACK_SIZE 4096
+#define UTEST_THR_PRIORITY 20
+#define RT_USING_LWP
+
+/* RT-Thread Utestcases */
+
+#define RT_USING_UTESTCASES
+
+/* Utest Self Testcase */
+
+#define UTEST_SELF_PASS_TC
+
+/* Kernel memheap stability Testcase */
+
+#define UTEST_MEMHEAP_TC
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+
+/* Wiced WiFi */
+
+
+/* IoT Cloud */
+
+
+/* security packages */
+
+
+/* language packages */
+
+
+/* multimedia packages */
+
+
+/* tools packages */
+
+
+/* system packages */
+
+
+/* Micrium: Micrium software products porting for RT-Thread */
+
+
+/* peripheral libraries and drivers */
+
+
+/* AI packages */
+
+
+/* miscellaneous packages */
+
+
+/* samples: kernel and components samples */
+
+
+/* entertainment: terminal games and other interesting software packages */
+
+#define SOC_VEXPRESS_A9
+#define RT_USING_UART0
+#define RT_USING_UART1
+#define BSP_DRV_EMAC
+
+#endif

+ 1 - 0
examples/utest/testcases/Kconfig

@@ -8,6 +8,7 @@ config RT_USING_UTESTCASES
 if RT_USING_UTESTCASES
 
 source "$RTT_DIR/examples/utest/testcases/utest/Kconfig"
+source "$RTT_DIR/examples/utest/testcases/kernel/Kconfig"
 
 endif
 

+ 8 - 0
examples/utest/testcases/kernel/Kconfig

@@ -0,0 +1,8 @@
+menu "Kernel Testcase"
+
+config UTEST_MEMHEAP_TC
+    bool "memheap stability test"
+    default y
+    depends on RT_USING_MEMHEAP
+
+endmenu

+ 15 - 0
examples/utest/testcases/kernel/SConscript

@@ -0,0 +1,15 @@
+Import('rtconfig')
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Split('''
+''')
+
+if GetDepend(['UTEST_MEMHEAP_TC']):
+    src += ['memheap_tc.c']
+
+CPPPATH = [cwd]
+
+group = DefineGroup('utestcases', src, depend = [], CPPPATH = CPPPATH)
+
+Return('group')

+ 100 - 0
examples/utest/testcases/kernel/memheap_tc.c

@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-01-16     flybreak     the first version
+ */
+
+#include <rtthread.h>
+#include <stdlib.h>
+#include "utest.h"
+
+#define HEAP_SIZE        (64 * 1024)
+#define HEAP_ALIGN       (4)
+#define SLICE_NUM        (40)
+#define TEST_TIMES       (100000)
+#define HEAP_NAME        "heap1"
+#define SLICE_SIZE_MAX   (HEAP_SIZE/SLICE_NUM)
+
+static void memheap_test(void)
+{
+    struct rt_memheap heap1;
+    rt_uint32_t ptr_start;
+    void *ptr[SLICE_NUM];
+    int i, cnt = 0;
+
+    /* init heap */
+    ptr_start = (rt_uint32_t)rt_malloc_align(HEAP_SIZE, HEAP_ALIGN);
+    if (ptr_start == RT_NULL)
+    {
+        rt_kprintf("totle size too big,can not malloc memory!");
+        return;
+    }
+
+    rt_memheap_init(&heap1, HEAP_NAME, (void *)ptr_start, HEAP_SIZE);
+
+    /* test start */
+    for (i = 0; i < SLICE_NUM; i++)
+    {
+        ptr[i] = 0;
+    }
+    /* test alloc */
+    for (i = 0; i < SLICE_NUM; i++)
+    {
+        rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX;
+        ptr[i] = rt_memheap_alloc(&heap1, slice_size);
+    }
+    /* test realloc */
+    while (cnt < TEST_TIMES)
+    {
+        rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX;
+        rt_uint32_t ptr_index = rand() % SLICE_NUM;
+        rt_uint32_t operation = rand() % 2;
+
+        if (ptr[ptr_index])
+        {
+            if (operation == 0) /* free and malloc */
+            {
+                if (ptr[ptr_index])
+                {
+                    rt_memheap_free(ptr[ptr_index]);
+                }
+                ptr[ptr_index] = rt_memheap_alloc(&heap1, slice_size);
+            }
+            else /* realloc */
+            {
+                ptr[ptr_index] = rt_memheap_realloc(&heap1, ptr[ptr_index], slice_size);
+            }
+        }
+        cnt ++;
+        if (cnt % (TEST_TIMES / 10) == 0)
+        {
+            rt_kprintf(">");
+        }
+    }
+
+    rt_kprintf("test OK!\n");
+
+    /* test end */
+    rt_memheap_detach(&heap1);
+    rt_free_align((void *)ptr_start);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+    return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+    return RT_EOK;
+}
+
+static void testcase(void)
+{
+    UTEST_UNIT_RUN(memheap_test);
+}
+UTEST_TC_EXPORT(testcase, "testcases.kernel.memheap_tc", utest_tc_init, utest_tc_cleanup, 10);

+ 1 - 1
examples/utest/testcases/utest/pass_tc.c

@@ -43,4 +43,4 @@ static void testcase(void)
 {
     UTEST_UNIT_RUN(test_assert_pass);
 }
-UTEST_TC_EXPORT(testcase, "testcases.utest.pass_tc", utest_tc_init, utest_tc_cleanup, 10);
+UTEST_TC_EXPORT(testcase, "testcases.utest.pass_tc", utest_tc_init, utest_tc_cleanup, 10);

+ 35 - 33
src/memheap.c

@@ -17,6 +17,7 @@
  * 2013-05-24     Bernard      fix the rt_memheap_realloc issue.
  * 2013-07-11     Grissiom     fix the memory block splitting issue.
  * 2013-07-15     Grissiom     optimize rt_memheap_realloc
+ * 2021-06-03     Flybreak     Fix the crash problem after opening Oz optimization on ac6.
  */
 
 #include <rthw.h>
@@ -41,31 +42,31 @@
 rt_inline void rt_memheap_setname(struct rt_memheap_item *item, const char *name)
 {
     int index;
-    rt_uint8_t* ptr;
+    rt_uint8_t *ptr;
 
-    ptr = (rt_uint8_t*)&(item->next_free);
-    for (index = 0; index < sizeof(void*); index ++)
+    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 
+    else
     {
-        ptr = (rt_uint8_t*)&(item->prev_free);
-        for (index = 0; index < sizeof(void*) && (index + sizeof(void*))< RT_NAME_MAX; index ++)
+        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') break;
+            ptr[index] = name[sizeof(void *) + index];
         }
 
-        if (name[sizeof(void*) + index] == '\0') ptr[index] = '\0';
+        if (name[sizeof(void *) + index] == '\0') ptr[index] = '\0';
     }
 }
 
-void rt_mem_set_tag(void* ptr, const char* name)
+void rt_mem_set_tag(void *ptr, const char *name)
 {
-    struct rt_memheap_item* item;
+    struct rt_memheap_item *item;
 
     if (ptr && name)
     {
@@ -369,7 +370,8 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
     if (newsize > oldsize)
     {
         void *new_ptr;
-        struct rt_memheap_item *next_ptr;
+        /* Fix the crash problem after opening Oz optimization on ac6  */
+        volatile struct rt_memheap_item *next_ptr;
 
         /* lock memheap */
         result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
@@ -441,14 +443,14 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
 
                 next_ptr->prev          = header_ptr;
                 next_ptr->next          = header_ptr->next;
-                header_ptr->next->prev = next_ptr;
-                header_ptr->next       = next_ptr;
+                header_ptr->next->prev = (struct rt_memheap_item *)next_ptr;
+                header_ptr->next       = (struct rt_memheap_item *)next_ptr;
 
                 /* insert next_ptr to free list */
                 next_ptr->next_free = heap->free_list->next_free;
                 next_ptr->prev_free = heap->free_list;
-                heap->free_list->next_free->prev_free = next_ptr;
-                heap->free_list->next_free            = next_ptr;
+                heap->free_list->next_free->prev_free = (struct rt_memheap_item *)next_ptr;
+                heap->free_list->next_free            = (struct rt_memheap_item *)next_ptr;
                 RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x",
                                                 next_ptr->next_free,
                                                 next_ptr->prev_free));
@@ -666,17 +668,17 @@ void rt_memheap_free(void *ptr)
 RTM_EXPORT(rt_memheap_free);
 
 #ifdef RT_USING_FINSH
-static void _memheap_dump_tag(struct rt_memheap_item* item)
+static void _memheap_dump_tag(struct rt_memheap_item *item)
 {
-    rt_uint8_t name[2 * sizeof(void*)];
-    rt_uint8_t* ptr;
+    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*));
+    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);
+    rt_kprintf("%.*s", 2 * sizeof(void *), name);
 }
 
 int rt_memheap_dump(struct rt_memheap *heap)
@@ -686,15 +688,15 @@ int rt_memheap_dump(struct rt_memheap *heap)
     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[%.*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);
+    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))
@@ -730,13 +732,13 @@ int memheaptrace(void)
         int index;
         extern int list_memheap(void);
 
-        heaps = (struct rt_memheap**)rt_malloc(sizeof(struct rt_memheap*) * count);
+        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);
+        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]);
@@ -966,15 +968,15 @@ void dump_used_memheap(struct rt_memheap *mh)
         {
             /* 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]);
+                       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]);
+                       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 */