1 /*
2 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "os_thread.h"
31 #include "os_util.h"
32
33
34 /**
35 * @brief Create and start a thread
36 *
37 * This function starts a new thread. The new thread starts execution by
38 * invoking entry(). The argument arg is passed as the sole argument of entry().
39 *
40 * @note After finishing execution, the new thread should call OS_ThreadDelete()
41 * to delete itself. Failing to do this and just returning from entry()
42 * will result in undefined behavior.
43 *
44 * @param[in] thread Pointer to the thread object
45 * @param[in] name A descriptive name for the thread. This is mainly used to
46 * facilitate debugging.
47 * @param[in] entry Entry, which is a function pointer, to the thread function
48 * @param[in] arg The sole argument passed to entry()
49 * @param[in] priority The priority at which the thread will execute
50 * @param[in] stackSize The number of bytes the thread stack can hold
51 * @retval OS_Status, OS_OK on success
52 */
OS_ThreadCreate(OS_Thread_t * thread,const char * name,OS_ThreadEntry_t entry,void * arg,OS_Priority priority,uint32_t stackSize)53 OS_Status OS_ThreadCreate(OS_Thread_t *thread, const char *name,
54 OS_ThreadEntry_t entry, void *arg,
55 OS_Priority priority, uint32_t stackSize)
56 {
57 OS_HANDLE_ASSERT(!OS_ThreadIsValid(thread), thread->handle);
58
59 thread->handle = rt_thread_create(name, entry, arg, stackSize,
60 priority, 20);
61
62 OS_DBG("%s(), name \"%s\", priority %d, stackSize %u, handle %p\n",
63 __func__, name, priority, (unsigned int)stackSize, thread->handle);
64
65 if (thread->handle == NULL) {
66 OS_ERR("rt_thread_create() failed!\n");
67 OS_ThreadSetInvalid(thread);
68 return OS_FAIL;
69 } else {
70 rt_thread_startup(thread->handle);
71 }
72 return OS_OK;
73 }
74
75 /**
76 * @brief Terminate the thread
77 * @note Only memory that is allocated to a thread by the kernel itself is
78 * automatically freed when a thread is deleted. Memory, or any other
79 * resource, that the application (rather than the kernel) allocates
80 * to a thread must be explicitly freed by the application when the task
81 * is deleted.
82 * @param[in] thread Pointer to the thread object to be deleted.
83 * A thread can delete itself by passing NULL in place of a
84 * valid thread object.
85 * @retval OS_Status, OS_OK on success
86 */
OS_ThreadDelete(OS_Thread_t * thread)87 OS_Status OS_ThreadDelete(OS_Thread_t *thread)
88 {
89 rt_thread_t handle;
90 rt_thread_t curHandle;
91
92 OS_DBG("%s(), handle %p\n", __func__, thread->handle);
93
94 if (thread == NULL) {
95 // vTaskDelete(NULL); /* delete self */
96 // OS_ERR("thread == NULL, %s delete self NC\n", __FUNCTION__);
97 return OS_OK;
98 }
99
100 OS_HANDLE_ASSERT(OS_ThreadIsValid(thread), thread->handle);
101
102 handle = thread->handle;
103 curHandle = OS_ThreadGetCurrentHandle();
104 if (handle == curHandle) {
105 /* delete self */
106 OS_ThreadSetInvalid(thread);
107 // vTaskDelete(NULL);
108 // OS_ERR("%s delete self NC\r\n", __FUNCTION__);
109 } else {
110 /* delete other thread */
111 OS_WRN("thread %"OS_HANDLE_F" delete %"OS_HANDLE_F"\n", curHandle, handle);
112 // vTaskDelete(handle);
113 rt_thread_delete(handle);
114 OS_ThreadSetInvalid(thread);
115 }
116
117 return OS_OK;
118 }
119