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