From 2d54fcc40581c348959e50a853ef7d4c0478974f Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Wed, 17 Mar 2010 09:57:07 +0000 Subject: [PATCH] add heap and semaphore examples. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@501 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- examples/kernel/SConscript | 7 ++ examples/kernel/heap_malloc.c | 72 ++++++++++++ examples/kernel/heap_realloc.c | 83 ++++++++++++++ examples/kernel/semaphore_buffer_worker.c | 121 ++++++++++++++++++++ examples/kernel/semaphore_dynamic.c | 86 +++++++++++++++ examples/kernel/semaphore_priority.c | 128 ++++++++++++++++++++++ examples/kernel/semaphore_static.c | 102 +++++++++++++++++ 7 files changed, 599 insertions(+) create mode 100644 examples/kernel/heap_malloc.c create mode 100644 examples/kernel/heap_realloc.c create mode 100644 examples/kernel/semaphore_buffer_worker.c create mode 100644 examples/kernel/semaphore_dynamic.c create mode 100644 examples/kernel/semaphore_priority.c create mode 100644 examples/kernel/semaphore_static.c diff --git a/examples/kernel/SConscript b/examples/kernel/SConscript index 3977040d0c..30da9421ab 100644 --- a/examples/kernel/SConscript +++ b/examples/kernel/SConscript @@ -9,9 +9,16 @@ thread_same_priority.c thread_static_simple.c thread_dynamic_simple.c thread_delete.c +semaphore_static.c +semaphore_dynamic.c +semaphore_priority.c +semaphore_buffer_worker.c +heap_malloc.c +heap_realloc.c """) # The set of source files associated with this SConscript file. obj = env.Object(src_local) +env.Append(CPPDEFINES='RT_USING_TC') Return('obj') diff --git a/examples/kernel/heap_malloc.c b/examples/kernel/heap_malloc.c new file mode 100644 index 0000000000..236a982fdf --- /dev/null +++ b/examples/kernel/heap_malloc.c @@ -0,0 +1,72 @@ +#include +#include "tc_comm.h" + +/* + * This is an example for heap malloc + */ + +static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) +{ + while (len) + { + if (*ptr != value) return RT_FALSE; + + ptr ++; + len --; + } + + return RT_TRUE; +} + +static void heap_malloc_init() +{ + rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + + ptr1 = rt_malloc(1); + ptr2 = rt_malloc(13); + ptr3 = rt_malloc(31); + ptr4 = rt_malloc(127); + ptr5 = rt_malloc(0); + + memset(ptr1, 1, 1); + memset(ptr2, 2, 13); + memset(ptr3, 3, 31); + memset(ptr4, 4, 127); + + if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; + if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; + if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; + if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; + + rt_free(ptr4); + rt_free(ptr3); + rt_free(ptr3); + rt_free(ptr1); + + if (ptr5 != RT_NULL) + { + rt_free(ptr5); + } + + tc_done(TC_STAT_PASSED); + +_failed: + tc_done(TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +int _tc_heap_malloc() +{ + heap_malloc_init(); + + return 0; +} +FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test); +#else +int rt_application_init() +{ + heap_malloc_init(); + + return 0; +} +#endif diff --git a/examples/kernel/heap_realloc.c b/examples/kernel/heap_realloc.c new file mode 100644 index 0000000000..5fa96c7f30 --- /dev/null +++ b/examples/kernel/heap_realloc.c @@ -0,0 +1,83 @@ +#include +#include "tc_comm.h" + +/* + * This is an example for heap malloc + */ + +static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len) +{ + while (len) + { + if (*ptr != value) return RT_FALSE; + + ptr ++; + len --; + } + + return RT_TRUE; +} + +static void heap_realloc_init() +{ + rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + + ptr1 = rt_malloc(1); + ptr2 = rt_malloc(13); + ptr3 = rt_malloc(31); + ptr4 = rt_malloc(127); + ptr5 = rt_malloc(0); + + memset(ptr1, 1, 1); + memset(ptr2, 2, 13); + memset(ptr3, 3, 31); + memset(ptr4, 4, 127); + + if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; + if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; + if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; + if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed; + + ptr1 = rt_realloc(ptr1, 13); + ptr2 = rt_realloc(ptr2, 31); + ptr3 = rt_realloc(ptr3, 127); + ptr4 = rt_realloc(ptr4, 1); + ptr5 = rt_realloc(ptr5, 0); + + if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed; + if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed; + if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed; + if (mem_check(ptr4, 4, 1) != RT_FALSE) goto _failed; + + rt_free(ptr4); + rt_free(ptr3); + rt_free(ptr3); + rt_free(ptr1); + + if (ptr5 != RT_NULL) + { + rt_free(ptr5); + } + + tc_done(TC_STAT_PASSED); + +_failed: + tc_done(TC_STAT_FAILED); +} + +#ifdef RT_USING_TC +int _tc_heap_realloc() +{ + heap_realloc_init(); + + return 0; +} +FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test); +#else +int rt_application_init() +{ + heap_realloc_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_buffer_worker.c b/examples/kernel/semaphore_buffer_worker.c new file mode 100644 index 0000000000..8dcf242063 --- /dev/null +++ b/examples/kernel/semaphore_buffer_worker.c @@ -0,0 +1,121 @@ +#include +#include "tc_comm.h" + +static rt_sem_t sem; +static rt_thread_t t1, worker; + +#define BUFFER_SIZE 256 +#define DATA_ITEM_SIZE 32 + +static rt_uint8_t working_buffer[BUFFER_SIZE]; +static rt_uint16_t write_index, read_index; + +static void thread1_entry(void* parameter) +{ + rt_err_t result; + rt_uint16_t next_index; + rt_uint8_t data[DATA_ITEM_SIZE]; + + while (1) + { + /* take a semaphore */ + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + return; + } + + /* read buffer */ + + /* release semaphore */ + rt_sem_release(sem); + } +} + +static void worker_thread_entry(void* parameter) +{ + rt_err_t result; + rt_uint16_t next_index; + rt_uint8_t data[DATA_ITEM_SIZE]; + + while (1) + { + /* take a semaphore */ + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + return; + } + + /* write buffer */ + + /* release semaphore */ + rt_sem_release(sem); + } +} + +int semaphore_buffer_worker_init() +{ + sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO); + if (sem == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + write_index = read_index = 0; + + t1 = rt_thread_create("t1", + thread1_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); + if (t1 != RT_NULL) + rt_thread_startup(t1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + worker = rt_thread_create("worker", + worker_thread_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (worker != RT_NULL) + rt_thread_startup(worker); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + /* delete t1, t2 and worker thread */ + rt_thread_delete(t1); + rt_thread_delete(worker); + + tc_stat(TC_STAT_PASSED); + + /* unlock scheduler */ + rt_exit_critical(); +} + +int _tc_semaphore_buffer_worker() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + semaphore_buffer_worker_init(); + + return 50; +} +FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, two threads working on a buffer example); +#else +int rt_application_init() +{ + semaphore_buffer_worker_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_dynamic.c b/examples/kernel/semaphore_dynamic.c new file mode 100644 index 0000000000..be49459a4d --- /dev/null +++ b/examples/kernel/semaphore_dynamic.c @@ -0,0 +1,86 @@ +#include +#include "tc_comm.h" + +static rt_sem_t sem; +static void thread_entry(void* parameter) +{ + rt_err_t result; + rt_tick_t tick; + + /* get current tick */ + tick = rt_tick_get(); + + /* take a semaphore for 10 OS Tick */ + result = rt_sem_take(sem, 10); + if (result == -RT_ETIMEOUT) + { + if (rt_tick_get() - tick != 10) + { + tc_done(TC_STAT_FAILED); + rt_sem_delete(sem); + return; + } + rt_kprintf("take semaphore timeout"); + } + else + { + tc_done(TC_STAT_FAILED); + rt_sem_delete(sem); + return; + } + + /* release semaphore one time */ + rt_sem_release(sem); + + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + rt_sem_delete(sem); + return; + } + + /* testcase passed */ + tc_done(TC_STAT_PASSED); + /* delete semaphore */ + rt_sem_delete(sem); +} + +int semaphore_dynamic_init() +{ + rt_thread_t tid; + + sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO); + if (sem == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + tid = rt_thread_create("test", + thread_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (tid != RT_NULL) + rt_thread_startup(tid); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +int _tc_semaphore_dynamic() +{ + semaphore_dynamic_init(); + + return 30; +} +FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore test); +#else +int rt_application_init() +{ + semaphore_dynamic_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_priority.c b/examples/kernel/semaphore_priority.c new file mode 100644 index 0000000000..766c25c514 --- /dev/null +++ b/examples/kernel/semaphore_priority.c @@ -0,0 +1,128 @@ +#include +#include "tc_comm.h" + +static rt_sem_t sem; +static rt_uint8_t t1_count, t2_count; +static rt_thread_t t1, t2, worker; +static void thread1_entry(void* parameter) +{ + rt_err_t result; + + while (1) + { + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + return; + } + + t1_count ++; + rt_kprintf("thread1: got semaphore, count: %d\n", t1_count); + } +} + +static void thread2_entry(void* parameter) +{ + rt_err_t result; + + while (1) + { + result = rt_sem_take(sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + return; + } + + t2_count ++; + rt_kprintf("thread2: got semaphore, count: %d\n", t2_count); + } +} + +static void worker_thread_entry(void* parameter) +{ + rt_thread_delay(10); + + while (1) + { + rt_sem_release(sem); + rt_thread_delay(5); + } +} + +int semaphore_priority_init() +{ + sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO); + if (sem == RT_NULL) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + t1_count = t2_count = 0; + + t1 = rt_thread_create("t1", + thread1_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); + if (t1 != RT_NULL) + rt_thread_startup(t1); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + t2 = rt_thread_create("t2", + thread2_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE); + if (t2 != RT_NULL) + rt_thread_startup(t2); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + worker = rt_thread_create("worker", + worker_thread_entry, RT_NULL, + THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (worker != RT_NULL) + rt_thread_startup(worker); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + /* delete t1, t2 and worker thread */ + rt_thread_delete(t1); + rt_thread_delete(t2); + rt_thread_delete(worker); + + if (t1_count > t2_count) + tc_stat(TC_STAT_FAILED); + else + tc_stat(TC_STAT_PASSED); + + /* unlock scheduler */ + rt_exit_critical(); +} + +int _tc_semaphore_priority() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + semaphore_priority_init(); + + return 50; +} +FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test); +#else +int rt_application_init() +{ + semaphore_priority_init(); + + return 0; +} +#endif diff --git a/examples/kernel/semaphore_static.c b/examples/kernel/semaphore_static.c new file mode 100644 index 0000000000..3b5cda3038 --- /dev/null +++ b/examples/kernel/semaphore_static.c @@ -0,0 +1,102 @@ +#include +#include "tc_comm.h" + +static struct rt_semaphore sem; +struct rt_thread thread; +static char thread_stack[THREAD_STACK_SIZE]; +static void thread_entry(void* parameter) +{ + rt_err_t result; + rt_tick_t tick; + + /* get current tick */ + tick = rt_tick_get(); + + /* take a semaphore for 10 OS Tick */ + result = rt_sem_take(&sem, 10); + if (result == -RT_ETIMEOUT) + { + if (rt_tick_get() - tick != 10) + { + tc_done(TC_STAT_FAILED); + rt_sem_detach(&sem); + return; + } + rt_kprintf("take semaphore timeout"); + } + else + { + tc_done(TC_STAT_FAILED); + rt_sem_detach(&sem); + return; + } + + /* release semaphore one time */ + rt_sem_release(&sem); + + result = rt_sem_take(&sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + tc_done(TC_STAT_FAILED); + rt_sem_detach(&sem); + return; + } + + /* testcase passed */ + tc_done(TC_STAT_PASSED); + /* detach semaphore */ + rt_sem_detach(&sem); +} + +int semaphore_static_init() +{ + rt_err_t result; + + result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) + { + tc_stat(TC_STAT_END | TC_STAT_FAILED); + return 0; + } + + result = rt_thread_init(&thread, "test", + thread_entry, RT_NULL, + thread_stack, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); + if (result == RT_EOK) + rt_thread_startup(&thread); + else + tc_stat(TC_STAT_END | TC_STAT_FAILED); + + return 0; +} + +#ifdef RT_USING_TC +static void _tc_cleanup() +{ + /* lock scheduler */ + rt_enter_critical(); + + if (thread.stat != RT_THREAD_CLOSE) + rt_thread_detach(&thread); + + /* unlock scheduler */ + rt_exit_critical(); +} + +int _tc_semaphore_static() +{ + /* set tc cleanup */ + tc_cleanup(_tc_cleanup); + semaphore_static_init(); + + return 30; +} +FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore test); +#else +int rt_application_init() +{ + semaphore_static_init(); + + return 0; +} +#endif -- GitLab