• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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