1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #ifndef __OAL_LINUX_THREAD_H__
20 #define __OAL_LINUX_THREAD_H__
21
22 /* ****************************************************************************
23 1 其他头文件包含
24 **************************************************************************** */
25 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
26 #include <asm/atomic.h>
27 #include <linux/spinlock.h>
28 #include <linux/interrupt.h>
29 #include <linux/wait.h>
30 #include <linux/jiffies.h>
31 #include <linux/time.h>
32 #include <asm/param.h>
33 #include <linux/timer.h>
34 #include <linux/sched.h>
35 #include <linux/sched/signal.h>
36 #include <linux/version.h>
37 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
38 #include <uapi/linux/sched/types.h>
39 #endif
40 #ifndef HAVE_PCLINT_CHECK
41 #include <linux/kthread.h>
42 #endif
43 #endif
44 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
45 #include <los_task.h>
46 #endif
47 #include "oal_util.h"
48
49 #ifdef __cplusplus
50 #if __cplusplus
51 extern "C" {
52 #endif
53 #endif
54
55 /* ****************************************************************************
56 2 STRUCT定义
57 **************************************************************************** */
58 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
59 typedef struct task_struct oal_kthread_stru;
60 #endif
61
62 typedef struct _kthread_param_ {
63 hi_u32 ul_stacksize;
64 hi_s32 l_prio;
65 hi_s32 l_policy;
66 hi_s32 l_cpuid;
67 hi_s32 l_nice;
68 } oal_kthread_param_stru;
69
70 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
71 #define LOS_TASK_CB LosTaskCB
72 #define pcTaskName taskName
73 #define uwTaskID taskID
74 #define pstRunTask runTask
75 #define g_pstTaskCBArray g_taskCBArray
76 #define g_stLosTask g_losTask
77 typedef LOS_TASK_CB oal_kthread_stru;
78 #endif
79
80 /* ****************************************************************************
81 3 枚举定义
82 **************************************************************************** */
83 /* ****************************************************************************
84 4 全局变量声明
85 **************************************************************************** */
86 /* ****************************************************************************
87 5 消息头定义
88 **************************************************************************** */
89 /* ****************************************************************************
90 6 消息定义
91 **************************************************************************** */
92 /* ****************************************************************************
93 7 宏定义
94 **************************************************************************** */
95 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
96
97 #define oal_kthread_should_stop kthread_should_stop
98 #define oal_schedule schedule
99
100 #define OAL_CURRENT current
101 #endif
102
103 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
104 #define OAL_CURRENT oal_get_current()
105 #endif
106
107 #define OAL_SCHED_FIFO 1
108 #define OAL_SCHED_RR 2
109 #define NOT_BIND_CPU (-1)
110
111 /* ****************************************************************************
112 8 UNION定义
113 **************************************************************************** */
114 /* ****************************************************************************
115 9 OTHERS定义
116 **************************************************************************** */
117 typedef int (*oal_thread_func)(void *);
118
119 /* ****************************************************************************
120 10 函数声明
121 **************************************************************************** */
122 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
oal_kthread_create(char * pc_thread_name,oal_thread_func pf_threadfn,void * p_data,const oal_kthread_param_stru * thread_param)123 static inline oal_kthread_stru *oal_kthread_create(char *pc_thread_name, oal_thread_func pf_threadfn, void *p_data,
124 const oal_kthread_param_stru *thread_param)
125 {
126 hi_s32 uwRet;
127 oal_kthread_stru *kthread = NULL;
128 struct sched_param st_sched_param;
129 OAL_BUG_ON(!thread_param);
130
131 kthread = kthread_create(pf_threadfn, p_data, "%s", pc_thread_name);
132 if (IS_ERR_OR_NULL(kthread)) {
133 oal_io_print1("failed to run theread:%s\n", pc_thread_name);
134 return NULL;
135 }
136
137 st_sched_param.sched_priority = thread_param->l_prio;
138 uwRet = sched_setscheduler(kthread, thread_param->l_policy, &st_sched_param);
139 if (oal_unlikely(uwRet)) {
140 oal_io_print3("%s sched_setscheduler failed! ret =%d, prio=%d\n", pc_thread_name, uwRet, thread_param->l_prio);
141 }
142
143 if (thread_param->l_cpuid >= 0) { /* cpuid为负数时无效 */
144 kthread_bind(kthread, thread_param->l_cpuid);
145 } else {
146 oal_io_print0("did not bind cpu...\n");
147 }
148 wake_up_process(kthread);
149 return kthread;
150 }
151
oal_set_thread_property(oal_kthread_stru * pst_thread,oal_kthread_param_stru * thread_param)152 static inline hi_u32 oal_set_thread_property(oal_kthread_stru *pst_thread, oal_kthread_param_stru *thread_param)
153 {
154 struct sched_param st_sched_param;
155 OAL_BUG_ON(!pst_thread);
156 OAL_BUG_ON(!thread_param);
157
158 st_sched_param.sched_priority = thread_param->l_prio;
159 oal_io_print1("set thread scheduler policy %d\n", thread_param->l_policy);
160
161 if (sched_setscheduler(pst_thread, thread_param->l_policy, &st_sched_param)) {
162 oal_io_print1("[Error]set scheduler failed! %d\n", thread_param->l_policy);
163 return -OAL_EFAIL;
164 }
165
166 if (thread_param->l_policy != SCHED_FIFO && thread_param->l_policy != SCHED_RR) {
167 oal_io_print1("set thread scheduler nice %d\n", thread_param->l_nice);
168 set_user_nice(pst_thread, thread_param->l_nice);
169 }
170 return HI_SUCCESS;
171 }
172
oal_kthread_stop(oal_kthread_stru * pst_thread)173 static inline hi_void oal_kthread_stop(oal_kthread_stru *pst_thread)
174 {
175 OAL_BUG_ON(!pst_thread);
176
177 send_sig(SIGTERM, pst_thread, 1);
178 kthread_stop(pst_thread);
179 }
180
oal_get_current_task_name(hi_void)181 static inline char *oal_get_current_task_name(hi_void)
182 {
183 return current->comm;
184 }
185 #endif
186
187 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
oal_kthread_create(char * pc_thread_name,oal_thread_func pf_threadfn,void * p_data,const oal_kthread_param_stru * thread_param)188 static inline oal_kthread_stru *oal_kthread_create(char *pc_thread_name, oal_thread_func pf_threadfn, void *p_data,
189 const oal_kthread_param_stru *thread_param)
190 {
191 hi_u32 ret;
192 TSK_INIT_PARAM_S st_sd_task;
193 hi_u32 ul_taskid;
194 oal_kthread_stru *kthread = NULL;
195 if (thread_param == HI_NULL) {
196 oal_io_print0("oal_kthread_create thread_param null\n");
197 return NULL;
198 }
199
200 /* 安全编程规则6.6例外(1) 固定长度的结构体进行内存初始化 */
201 memset_s(&st_sd_task, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
202 st_sd_task.pfnTaskEntry = (TSK_ENTRY_FUNC)pf_threadfn;
203 st_sd_task.auwArgs[0] = (uintptr_t)p_data;
204 st_sd_task.uwStackSize = thread_param->ul_stacksize;
205 st_sd_task.pcName = pc_thread_name;
206 st_sd_task.usTaskPrio = (hi_u16)thread_param->l_prio;
207 st_sd_task.uwResved = LOS_TASK_STATUS_DETACHED;
208 #ifdef LOSCFG_KERNEL_SMP
209 st_sd_task.usCpuAffiMask = CPUID_TO_AFFI_MASK(0);
210 #endif
211 ret = LOS_TaskCreate(&ul_taskid, &st_sd_task);
212 if (ret != 0) {
213 oal_io_print1("Failed to create %s thread\n", (uintptr_t)pc_thread_name);
214 return NULL;
215 }
216 if (g_pstTaskCBArray == HI_NULL) {
217 oal_io_print0("oal_kthread_create g_pstTaskCBArray null\n");
218 return NULL;
219 }
220
221 kthread = (oal_kthread_stru *)&g_pstTaskCBArray[ul_taskid];
222 return kthread;
223 }
224
225
oal_kthread_stop(const oal_kthread_stru * kthread)226 static inline hi_void oal_kthread_stop(const oal_kthread_stru *kthread)
227 {
228 hi_u32 ret;
229 if (oal_unlikely(kthread == NULL)) {
230 oal_io_print0("thread can't stop\n");
231 return;
232 }
233 oal_io_print1("%s thread stop\n", (uintptr_t)kthread->pcTaskName);
234 ret = LOS_TaskDelete(kthread->uwTaskID);
235 if (ret != 0) {
236 oal_io_print0("LOS_TaskDelete fail!\n");
237 }
238 }
239
oal_kthread_should_stop(hi_void)240 static inline hi_s32 oal_kthread_should_stop(hi_void)
241 {
242 return 0;
243 }
244
oal_set_thread_property(const oal_kthread_stru * thread,const oal_kthread_param_stru * thread_param)245 static inline hi_u32 oal_set_thread_property(const oal_kthread_stru *thread, const oal_kthread_param_stru *thread_param)
246 {
247 return LOS_TaskPriSet(thread->uwTaskID, thread_param->l_prio);
248 }
249 #endif
250 #ifdef __cplusplus
251 #if __cplusplus
252 }
253 #endif
254 #endif
255
256 #endif
257