更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
pthread.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "pprivate.h"
33#include "pthread.h"
34#include "sched.h"
35
36#include "stdio.h"
37#include "map_error.h"
38#include "los_process_pri.h"
39#include "los_sched_pri.h"
40
41// 本文件实现 liteos task 适配 pthread
42
43/*
44 * Array of pthread control structures. A pthread_t object is
45 * "just" an index into this array.
46 */
47STATIC _pthread_data g_pthreadData[LOSCFG_BASE_CORE_TSK_LIMIT + 1];//
48
49/* Count of number of threads that have exited and not been reaped. */
51
52/* this is to protect the pthread data */
53STATIC pthread_mutex_t g_pthreadsDataMutex = PTHREAD_MUTEX_INITIALIZER;
54
55/* pointed to by PTHREAD_CANCELED */
57
58/*
59 * Private version of pthread_self() that returns a pointer to our internal
60 * control structure.
61 */
62_pthread_data *pthread_get_self_data(void)//获取当前线程信息
63{
64 UINT32 runningTaskPID = ((LosTaskCB *)(OsCurrTaskGet()))->taskID;//当前线程
65 _pthread_data *data = &g_pthreadData[runningTaskPID];
66
67 return data;
68}
69///获取线程控制块
71{
72 _pthread_data *data = NULL;
73
74 if (OS_TID_CHECK_INVALID(id)) {
75 return NULL;
76 }
77
78 data = &g_pthreadData[id];
79 /* Check that this is a valid entry */
80 if ((data->state == PTHREAD_STATE_FREE) || (data->state == PTHREAD_STATE_EXITED)) {
81 return NULL;
82 }
83
84 /* Check that the entry matches the id */
85 if (data->id != id) {
86 return NULL;
87 }
88
89 /* Return the pointer */
90 return data;
91}
92
93/*
94 * Check whether there is a cancel pending and if so, whether
95 * cancellations are enabled. We do it in this order to reduce the
96 * number of tests in the common case - when no cancellations are
97 * pending. We make this inline so it can be called directly below for speed
98 */
100{
102 if (self->canceled && (self->cancelstate == PTHREAD_CANCEL_ENABLE)) {
103 return 1;
104 }
105 return 0;
106}
107
109{
110 data->state = PTHREAD_STATE_FREE;
111 (VOID)memset_s(data, sizeof(_pthread_data), 0, sizeof(_pthread_data));
112}
113
114/*
115 * This function is called to tidy up and dispose of any threads that have
116 * exited. This work must be done from a thread other than the one exiting.
117 * Note: this function must be called with pthread_mutex locked.
118 */
119STATIC VOID PthreadReap(VOID)
120{
121 UINT32 i;
122 _pthread_data *data = NULL;
123 /*
124 * Loop over the thread table looking for exited threads. The
125 * g_pthreadsExited counter springs us out of this once we have
126 * found them all (and keeps us out if there are none to do).
127 */
128 for (i = 0; g_pthreadsExited && (i < g_taskMaxNum); i++) {
129 data = &g_pthreadData[i];
130 if (data->state == PTHREAD_STATE_EXITED) {
131 /* the Huawei LiteOS not delete the dead TCB,so need to delete the TCB */
132 (VOID)LOS_TaskDelete(data->task->taskID);
133 if (data->task->taskStatus & OS_TASK_STATUS_UNUSED) {
136 }
137 }
138 }
139}
140///设置线程的属性
141STATIC VOID SetPthreadAttr(const _pthread_data *self, const pthread_attr_t *attr, pthread_attr_t *outAttr)
142{
143 /*
144 * Set use_attr to the set of attributes we are going to
145 * actually use. Either those passed in, or the default set.
146 */
147 if (attr == NULL) {
148 (VOID)pthread_attr_init(outAttr);
149 } else {
150 (VOID)memcpy_s(outAttr, sizeof(pthread_attr_t), attr, sizeof(pthread_attr_t));
151 }
152
153 /*
154 * If the stack size is not valid, we can assume that it is at
155 * least PTHREAD_STACK_MIN bytes.
156 */
157 if (!outAttr->stacksize_set) {
158 outAttr->stacksize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
159 }
160 if (outAttr->inheritsched == PTHREAD_INHERIT_SCHED) {
161 if (self->task == NULL) {
162 outAttr->schedparam.sched_priority = LOS_TaskPriGet(OsCurrTaskGet()->taskID);
163 } else {
164 outAttr->schedpolicy = self->attr.schedpolicy;
165 outAttr->schedparam = self->attr.schedparam;
166 outAttr->scope = self->attr.scope;
167 }
168 }
169}
170
171STATIC VOID SetPthreadDataAttr(const pthread_attr_t *userAttr, const pthread_t threadID,
172 LosTaskCB *taskCB, _pthread_data *created)
173{
174 created->attr = *userAttr;
175 created->id = threadID;
176 created->task = taskCB;
177 created->state = (userAttr->detachstate == PTHREAD_CREATE_JOINABLE) ?
178 PTHREAD_STATE_RUNNING : PTHREAD_STATE_DETACHED;
179 /* need to confirmation */
180 created->cancelstate = PTHREAD_CANCEL_ENABLE;
181 created->canceltype = PTHREAD_CANCEL_DEFERRED;
182 created->cancelbuffer = NULL;
183 created->canceled = 0;
184 created->freestack = 0; /* no use default : 0 */
185 created->stackmem = taskCB->topOfStack;
186 created->thread_data = NULL;
187}
188///线程控制块初始化
189STATIC UINT32 InitPthreadData(pthread_t threadID, pthread_attr_t *userAttr,
190 const CHAR name[], size_t len)
191{
192 errno_t err;
193 UINT32 ret = LOS_OK;
194 LosTaskCB *taskCB = OS_TCB_FROM_TID(threadID);
195 _pthread_data *created = &g_pthreadData[threadID];
196
197 err = strncpy_s(created->name, sizeof(created->name), name, len);
198 if (err != EOK) {
199 PRINT_ERR("%s: %d, err: %d\n", __FUNCTION__, __LINE__, err);
200 return LOS_NOK;
201 }
202 userAttr->stacksize = taskCB->stackSize;//内核栈大小
203 err = OsSetTaskName(taskCB, created->name, FALSE);
204 if (err != LOS_OK) {
205 PRINT_ERR("%s: %d, err: %d\n", __FUNCTION__, __LINE__, err);
206 return LOS_NOK;
207 }
208#ifdef LOSCFG_KERNEL_SMP
209 if (userAttr->cpuset.__bits[0] > 0) {
210 taskCB->cpuAffiMask = (UINT16)userAttr->cpuset.__bits[0];//CPU亲和力掩码
211 }
212#endif
213
214 SetPthreadDataAttr(userAttr, threadID, taskCB, created);
215 return ret;
216}
217
218/*!
219 * @brief pthread_create
220 * 创建线程
221 * @param arg 传递给线程入口函数的参数
222 * @param attr 指向线程属性的指针,如果使用 NULL,则使用默认的线程属性
223 * @param startRoutine 线程入口函数地址
224 * @param thread 指向线程句柄 (线程标识符) 的指针,不能为 NULL
225 * @return
226 *
227 * @see
228 */
229int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
230 void *(*startRoutine)(void *), void *arg)
231{
232 pthread_attr_t userAttr;
233 UINT32 ret;
234 CHAR name[PTHREAD_DATA_NAME_MAX] = {0};
235 STATIC UINT16 pthreadNumber = 1;
236 TSK_INIT_PARAM_S taskInitParam = {0};//posix线程对标鸿蒙内核的任务
237 UINT32 taskHandle;
239
240 if ((thread == NULL) || (startRoutine == NULL)) {
241 return EINVAL;
242 }
243
244 SetPthreadAttr(self, attr, &userAttr);//设置线程属性(包括栈信息 ==)
245
246 (VOID)snprintf_s(name, sizeof(name), sizeof(name) - 1, "pth%02d", pthreadNumber);
247 pthreadNumber++;
248
249 taskInitParam.pcName = name;
250 taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)startRoutine;//线程入口函数 类似 Java thread 的 run()函数
251 taskInitParam.auwArgs[0] = (UINTPTR)arg;//参数
252 taskInitParam.usTaskPrio = (UINT16)userAttr.schedparam.sched_priority;//任务优先级
253 taskInitParam.uwStackSize = userAttr.stacksize;//栈大小
254 if (OsProcessIsUserMode(OsCurrProcessGet())) {//@note_thinking 是不是搞反了 ?
255 taskInitParam.processID = OsGetKernelInitProcessID();//内核进程
256 } else {
257 taskInitParam.processID = OsCurrProcessGet()->processID;//这里可以看出
258 }
259 if (userAttr.detachstate == PTHREAD_CREATE_DETACHED) {
260 taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED;//detached状态的线程,在结束的时候,会自动释放该线程所占用的资源。
261 } else {
262 /* Set the pthread default joinable */
263 taskInitParam.uwResved = LOS_TASK_ATTR_JOINABLE;//如果使用 PTHREAD_CREATE_JOINABLE 创建非分离线程,
264 }//则假设应用程序将等待线程完成。也就是说,程序将对线程执行 pthread_join()。
265
266 PthreadReap();
267 ret = LOS_TaskCreateOnly(&taskHandle, &taskInitParam);//创建线程但不调度
268 if (ret == LOS_OK) {
269 *thread = (pthread_t)taskHandle;
270 ret = InitPthreadData(*thread, &userAttr, name, PTHREAD_DATA_NAME_MAX);
271 if (ret != LOS_OK) {
272 goto ERROR_OUT_WITH_TASK;
273 }
274 (VOID)LOS_SetTaskScheduler(taskHandle, SCHED_RR, taskInitParam.usTaskPrio);//设置调度器,等待调度
275 }
276
277 if (ret == LOS_OK) {
278 return ENOERR;
279 } else {
280 goto ERROR_OUT;
281 }
282
283ERROR_OUT_WITH_TASK:
284 (VOID)LOS_TaskDelete(taskHandle);
285ERROR_OUT:
286 *thread = (pthread_t)-1;
287
288 return map_errno(ret);
289}
290/// 线程退出
291void pthread_exit(void *retVal)
292{
294 UINT32 intSave;
295
296 if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, (int *)0) != ENOERR) {
297 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
298 }
299
300 if (pthread_mutex_lock(&g_pthreadsDataMutex) != ENOERR) {
301 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
302 }
303
304 self->task->joinRetval = retVal;
305 /*
306 * If we are already detached, go to EXITED state, otherwise
307 * go into JOIN state.
308 */
309 if (self->state == PTHREAD_STATE_DETACHED) {
310 self->state = PTHREAD_STATE_EXITED;
312 } else {
313 self->state = PTHREAD_STATE_JOIN;
314 }
315
317 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
318 }
319 SCHEDULER_LOCK(intSave);
320 /* If the thread is the highest thread,it can't schedule in LOS_SemPost. */
321 OsTaskJoinPostUnsafe(self->task);
322 if (self->task->taskStatus & OS_TASK_STATUS_RUNNING) {
324 }
325 SCHEDULER_UNLOCK(intSave);
326}
327
329{
330 UINT32 intSave;
331 INT32 err = 0;
332 UINT32 ret;
333 switch (joined->state) {
334 case PTHREAD_STATE_RUNNING:
335 /* The thread is still running, we must wait for it. */
336 SCHEDULER_LOCK(intSave);
337 ret = OsTaskJoinPendUnsafe(joined->task);
338 SCHEDULER_UNLOCK(intSave);
339 if (ret != LOS_OK) {
340 err = (INT32)ret;
341 break;
342 }
343
344 joined->state = PTHREAD_STATE_ALRDY_JOIN;
345 break;
346 /*
347 * The thread has become unjoinable while we waited, so we
348 * fall through to complain.
349 */
350 case PTHREAD_STATE_FREE:
351 case PTHREAD_STATE_DETACHED:
352 case PTHREAD_STATE_EXITED:
353 /* None of these may be joined. */
354 err = EINVAL;
355 break;
356 case PTHREAD_STATE_ALRDY_JOIN:
357 err = EINVAL;
358 break;
359 case PTHREAD_STATE_JOIN:
360 break;
361 default:
362 PRINT_ERR("state: %u is not supported\n", (UINT32)joined->state);
363 break;
364 }
365 return err;
366}
367
368int pthread_join(pthread_t thread, void **retVal)
369{
370 INT32 err;
371 UINT8 status;
372 _pthread_data *self = NULL;
373 _pthread_data *joined = NULL;
374
375 /* Check for cancellation first. */
377
378 /* Dispose of any dead threads */
380 PthreadReap();
382
383 self = pthread_get_self_data();
384 joined = pthread_get_data(thread);
385 if (joined == NULL) {
386 return ESRCH;
387 }
388 status = joined->state;
389
390 if (joined == self) {
391 return EDEADLK;
392 }
393
394 err = ProcessByJoinState(joined);
396
397 if (!err) {
398 /*
399 * Here, we know that joinee is a thread that has exited and is
400 * ready to be joined.
401 */
402 if (retVal != NULL) {
403 /* Get the retVal */
404 *retVal = joined->task->joinRetval;
405 }
406
407 /* Set state to exited. */
408 joined->state = PTHREAD_STATE_EXITED;
410
411 /* Dispose of any dead threads */
412 PthreadReap();
413 } else {
414 joined->state = status;
415 }
416
418 /* Check for cancellation before returning */
420
421 return err;
422}
423
424/*
425 * Set the detachstate of the thread to "detached". The thread then does not
426 * need to be joined and its resources will be freed when it exits.
427 * 调用此函数,如果 pthread 线程没有结束,则将 thread 线程属性的分离状态设置为 detached;
428 * 当 thread 线程已经结束时,系统将回收 pthread 线程占用的资源。
429 */
430int pthread_detach(pthread_t thread)
431{
432 int ret = 0;
433 UINT32 intSave;
434
435 _pthread_data *detached = NULL;
436
437 if (pthread_mutex_lock(&g_pthreadsDataMutex) != ENOERR) {
438 ret = ESRCH;
439 }
440 detached = pthread_get_data(thread);
441 if (detached == NULL) {
442 ret = ESRCH; /* No such thread */
443 } else if (detached->state == PTHREAD_STATE_DETACHED) {
444 ret = EINVAL; /* Already detached! */
445 } else if (detached->state == PTHREAD_STATE_JOIN) {
446 detached->state = PTHREAD_STATE_EXITED;
448 } else {
449 /* Set state to detached and kick any joinees to make them return. */
450 SCHEDULER_LOCK(intSave);
451 if (!(detached->task->taskStatus & OS_TASK_STATUS_EXIT)) {
452 ret = OsTaskSetDetachUnsafe(detached->task);
453 if (ret == ESRCH) {
454 ret = LOS_OK;
455 } else if (ret == LOS_OK) {
456 detached->state = PTHREAD_STATE_DETACHED;
457 }
458 } else {
459 detached->state = PTHREAD_STATE_EXITED;
461 }
462 SCHEDULER_UNLOCK(intSave);
463 }
464
465 /* Dispose of any dead threads */
466 PthreadReap();
468 ret = ESRCH;
469 }
470
471 return ret;
472}
473///设置调度参数
474int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)
475{
476 _pthread_data *data = NULL;
477 int ret;
478
479 if ((param == NULL) || (param->sched_priority > OS_TASK_PRIORITY_LOWEST)) {
480 return EINVAL;
481 }
482
483 if (policy != SCHED_RR) {
484 return EINVAL;
485 }
486
487 /* The parameters seem OK, change the thread. */
489 if (ret != ENOERR) {
490 return ret;
491 }
492
493 data = pthread_get_data(thread);
494 if (data == NULL) {
496 if (ret != ENOERR) {
497 return ret;
498 }
499 return ESRCH;
500 }
501
502 /* Only support one policy now */
503 data->attr.schedpolicy = SCHED_RR;
504 data->attr.schedparam = *param;
505
507 if (ret != ENOERR) {
508 return ret;
509 }
510 (VOID)LOS_TaskPriSet((UINT32)thread, (UINT16)param->sched_priority);
511
512 return ENOERR;
513}
514
515int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
516{
517 _pthread_data *data = NULL;
518 int ret;
519
520 if ((policy == NULL) || (param == NULL)) {
521 return EINVAL;
522 }
523
525 if (ret != ENOERR) {
526 return ret;
527 }
528
529 data = pthread_get_data(thread);
530 if (data == NULL) {
531 goto ERR_OUT;
532 }
533
534 *policy = data->attr.schedpolicy;
535 *param = data->attr.schedparam;
536
538 return ret;
539ERR_OUT:
541 if (ret != ENOERR) {
542 return ret;
543 }
544 return ESRCH;
545}
546
547/* Call initRoutine just the once per control variable. */
548int pthread_once(pthread_once_t *onceControl, void (*initRoutine)(void))
549{
550 pthread_once_t old;
551 int ret;
552
553 if ((onceControl == NULL) || (initRoutine == NULL)) {
554 return EINVAL;
555 }
556
557 /* Do a test and set on the onceControl object. */
559 if (ret != ENOERR) {
560 return ret;
561 }
562
563 old = *onceControl;
564 *onceControl = 1;
565
567 if (ret != ENOERR) {
568 return ret;
569 }
570 /* If the onceControl was zero, call the initRoutine(). */
571 if (!old) {
572 initRoutine();
573 }
574
575 return ENOERR;
576}
577
578/* Thread specific data */
579int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
580{
581 (VOID)key;
582 (VOID)destructor;
583 PRINT_ERR("[%s] is not support.\n", __FUNCTION__);
584 return 0;
585}
586
587/* Store the pointer value in the thread-specific data slot addressed by the key. */
588int pthread_setspecific(pthread_key_t key, const void *pointer)
589{
590 (VOID)key;
591 (VOID)pointer;
592 PRINT_ERR("[%s] is not support.\n", __FUNCTION__);
593 return 0;
594}
595
596/* Retrieve the pointer value in the thread-specific data slot addressed by the key. */
597void *pthread_getspecific(pthread_key_t key)
598{
599 (VOID)key;
600 PRINT_ERR("[%s] is not support.\n", __FUNCTION__);
601 return NULL;
602}
603
604/*
605 * Set cancel state of current thread to ENABLE or DISABLE.
606 * Returns old state in *oldState.
607 */
608int pthread_setcancelstate(int state, int *oldState)
609{
610 _pthread_data *self = NULL;
611 int ret;
612
613 if ((state != PTHREAD_CANCEL_ENABLE) && (state != PTHREAD_CANCEL_DISABLE)) {
614 return EINVAL;
615 }
616
618 if (ret != ENOERR) {
619 return ret;
620 }
621
622 self = pthread_get_self_data();
623
624 if (oldState != NULL) {
625 *oldState = self->cancelstate;
626 }
627
628 self->cancelstate = (UINT8)state;
629
631 if (ret != ENOERR) {
632 return ret;
633 }
634
635 return ENOERR;
636}
637
638/*
639 * Set cancel type of current thread to ASYNCHRONOUS or DEFERRED.
640 * Returns old type in *oldType.
641 */
642int pthread_setcanceltype(int type, int *oldType)
643{
644 _pthread_data *self = NULL;
645 int ret;
646
647 if ((type != PTHREAD_CANCEL_ASYNCHRONOUS) && (type != PTHREAD_CANCEL_DEFERRED)) {
648 return EINVAL;
649 }
650
652 if (ret != ENOERR) {
653 return ret;
654 }
655
656 self = pthread_get_self_data();
657 if (oldType != NULL) {
658 *oldType = self->canceltype;
659 }
660
661 self->canceltype = (UINT8)type;
662
664 if (ret != ENOERR) {
665 return ret;
666 }
667
668 return ENOERR;
669}
670
672{
673 UINT32 ret = LOS_OK;
674 UINT32 intSave;
675 LOS_TaskLock();
676 data->canceled = 0;
677 if ((data->task->taskStatus & OS_TASK_STATUS_EXIT) || (LOS_TaskSuspend(data->task->taskID) != ENOERR)) {
678 ret = LOS_NOK;
679 goto OUT;
680 }
681
682 if (data->task->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
683 SCHEDULER_LOCK(intSave);
685 SCHEDULER_UNLOCK(intSave);
686 g_pthreadCanceledDummyVar = (UINTPTR)PTHREAD_CANCELED;
688 } else if (data->state && !(data->task->taskStatus & OS_TASK_STATUS_UNUSED)) {
689 data->state = PTHREAD_STATE_EXITED;
691 PthreadReap();
692 } else {
693 ret = LOS_NOK;
694 }
695OUT:
697 return ret;
698}
699
700int pthread_cancel(pthread_t thread)
701{
702 _pthread_data *data = NULL;
703
704 if (pthread_mutex_lock(&g_pthreadsDataMutex) != ENOERR) {
705 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
706 }
707
708 data = pthread_get_data(thread);
709 if (data == NULL) {
711 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
712 }
713 return ESRCH;
714 }
715
716 data->canceled = 1;
717
718 if ((data->cancelstate == PTHREAD_CANCEL_ENABLE) &&
719 (data->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)) {
720 /*
721 * If the thread has cancellation enabled, and it is in
722 * asynchronous mode, suspend it and set corresponding thread's status.
723 * We also release the thread out of any current wait to make it wake up.
724 */
725 if (DoPthreadCancel(data) == LOS_NOK) {
726 goto ERROR_OUT;
727 }
728 }
729
730 /*
731 * Otherwise the thread has cancellation disabled, in which case
732 * it is up to the thread to enable cancellation
733 */
735 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
736 }
737
738 return ENOERR;
739ERROR_OUT:
741 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
742 }
743 return ESRCH;
744}
745
746/*
747 * Test for a pending cancellation for the current thread and terminate
748 * the thread if there is one.
749 */
751{
752 if (CheckForCancel()) {
753 /*
754 * If we have cancellation enabled, and there is a cancellation
755 * pending, then go ahead and do the deed.
756 * Exit now with special retVal. pthread_exit() calls the
757 * cancellation handlers implicitly.
758 */
759 pthread_exit((void *)PTHREAD_CANCELED);
760 }
761}
762
763/* Get current thread id. */
764pthread_t pthread_self(void)//获取当前线程ID
765{
767
768 return data->id;
769}
770
771/* Compare two thread identifiers. */
772int pthread_equal(pthread_t thread1, pthread_t thread2)
773{
774 return thread1 == thread2;
775}
776
777void pthread_cleanup_push_inner(struct pthread_cleanup_buffer *buffer,
778 void (*routine)(void *), void *arg)
779{
780 (VOID)buffer;
781 (VOID)routine;
782 (VOID)arg;
783 PRINT_ERR("[%s] is not support.\n", __FUNCTION__);
784 return;
785}
786
787void pthread_cleanup_pop_inner(struct pthread_cleanup_buffer *buffer, int execute)
788{
789 (VOID)buffer;
790 (VOID)execute;
791 PRINT_ERR("[%s] is not support.\n", __FUNCTION__);
792 return;
793}
794
795/*
796 * Set the cpu affinity mask for the thread | 设置线程与CPU的亲和性
797 */
798int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t* cpuset)
799{
800 INT32 ret = sched_setaffinity(thread, cpusetsize, cpuset);
801 if (ret == -1) {
802 return errno;
803 } else {
804 return ENOERR;
805 }
806}
807
808/*
809 * Get the cpu affinity mask from the thread | 获取线程与CPU的亲和性
810 */
811int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t* cpuset)
812{
813 INT32 ret = sched_getaffinity(thread, cpusetsize, cpuset);
814 if (ret == -1) {
815 return errno;
816 } else {
817 return ENOERR;
818 }
819}
820
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
Unlock the task scheduling.
Definition: los_task.c:1148
LITE_OS_SEC_BSS UINT32 g_taskMaxNum
任务最大数量 默认128个
Definition: los_task.c:150
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
Delete a task.
Definition: los_task.c:968
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
获取任务的优先级
Definition: los_task.c:1050
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
设置指定任务的优先级
Definition: los_task.c:1071
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
LOS_TaskCreateOnly 创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态
Definition: los_task.c:663
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
Set the scheduling policy and priority for the task.
Definition: los_task.c:1493
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
外部接口,对OsTaskSuspend的封装
Definition: los_task.c:855
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
Lock the task scheduling.
Definition: los_task.c:1139
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID)
获取内核态根进程
Definition: los_process.c:2249
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
VOID OsSchedResched(VOID)
Definition: los_sched.c:449
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务
Definition: los_task.c:224
LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName)
Definition: los_task.c:1337
LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
OsTaskJoinPostUnsafe 查找task 通过 OS_TCB_FROM_PENDLIST 来完成,相当于由LOS_DL_LIST找到LosTaskCB,...
Definition: los_task.c:212
LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
任务设置分离模式 Deatch和JOIN是一对有你没我的状态
Definition: los_task.c:243
unsigned short UINT16
Definition: los_typedef.h:56
signed int INT32
Definition: los_typedef.h:60
unsigned char UINT8
Definition: los_typedef.h:55
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
int map_errno(UINT32 err)
Definition: map_error.c:38
_pthread_data * pthread_get_self_data(void)
Definition: pthread.c:62
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)
设置调度参数
Definition: pthread.c:474
STATIC _pthread_data g_pthreadData[LOSCFG_BASE_CORE_TSK_LIMIT+1]
Definition: pthread.c:47
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset)
Definition: pthread.c:798
STATIC INT32 CheckForCancel(VOID)
Definition: pthread.c:99
void pthread_exit(void *retVal)
线程退出
Definition: pthread.c:291
STATIC INT32 g_pthreadsExited
Definition: pthread.c:50
UINTPTR g_pthreadCanceledDummyVar
Definition: pthread.c:56
int pthread_setcanceltype(int type, int *oldType)
Definition: pthread.c:642
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*startRoutine)(void *), void *arg)
pthread_create 创建线程
Definition: pthread.c:229
STATIC UINT32 InitPthreadData(pthread_t threadID, pthread_attr_t *userAttr, const CHAR name[], size_t len)
线程控制块初始化
Definition: pthread.c:189
pthread_t pthread_self(void)
Definition: pthread.c:764
STATIC VOID SetPthreadDataAttr(const pthread_attr_t *userAttr, const pthread_t threadID, LosTaskCB *taskCB, _pthread_data *created)
Definition: pthread.c:171
int pthread_equal(pthread_t thread1, pthread_t thread2)
Definition: pthread.c:772
_pthread_data * pthread_get_data(pthread_t id)
获取线程控制块
Definition: pthread.c:70
STATIC VOID PthreadReap(VOID)
Definition: pthread.c:119
int pthread_detach(pthread_t thread)
Definition: pthread.c:430
int pthread_once(pthread_once_t *onceControl, void(*initRoutine)(void))
Definition: pthread.c:548
STATIC VOID SetPthreadAttr(const _pthread_data *self, const pthread_attr_t *attr, pthread_attr_t *outAttr)
设置线程的属性
Definition: pthread.c:141
STATIC INT32 ProcessByJoinState(_pthread_data *joined)
Definition: pthread.c:328
int pthread_cancel(pthread_t thread)
Definition: pthread.c:700
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
Definition: pthread.c:515
STATIC pthread_mutex_t g_pthreadsDataMutex
Definition: pthread.c:53
int pthread_setcancelstate(int state, int *oldState)
Definition: pthread.c:608
void pthread_cleanup_push_inner(struct pthread_cleanup_buffer *buffer, void(*routine)(void *), void *arg)
Definition: pthread.c:777
void pthread_cleanup_pop_inner(struct pthread_cleanup_buffer *buffer, int execute)
Definition: pthread.c:787
int pthread_setspecific(pthread_key_t key, const void *pointer)
Definition: pthread.c:588
void * pthread_getspecific(pthread_key_t key)
Definition: pthread.c:597
STATIC UINT32 DoPthreadCancel(_pthread_data *data)
Definition: pthread.c:671
int pthread_join(pthread_t thread, void **retVal)
Definition: pthread.c:368
void pthread_testcancel(void)
Definition: pthread.c:750
int pthread_key_create(pthread_key_t *key, void(*destructor)(void *))
Definition: pthread.c:579
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset)
Definition: pthread.c:811
STATIC VOID ProcessUnusedStatusTask(_pthread_data *data)
Definition: pthread.c:108
int pthread_attr_init(pthread_attr_t *attr)
Definition: pthread_attr.c:36
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
int sched_getaffinity(pid_t pid, size_t set_size, cpu_set_t *set)
Definition: sched.c:95
int sched_setaffinity(pid_t pid, size_t set_size, const cpu_set_t *set)
Definition: sched.c:63
CHAR name[PTHREAD_DATA_NAME_MAX]
Definition: pprivate.h:56
UINT32 freestack
Definition: pprivate.h:62
UINT32 stackmem
Definition: pprivate.h:63
VOID ** thread_data
Definition: pprivate.h:64
struct pthread_cleanup_buffer * cancelbuffer
Definition: pprivate.h:61
LosTaskCB * task
Definition: pprivate.h:55
pthread_attr_t attr
Definition: pprivate.h:53
pthread_t id
Definition: pprivate.h:54
UINT8 state
Definition: pprivate.h:57
volatile UINT8 canceltype
Definition: pprivate.h:59
volatile UINT8 canceled
Definition: pprivate.h:60
UINT8 cancelstate
Definition: pprivate.h:58
UINT32 processID
VOID * joinRetval
UINT16 cpuAffiMask
UINT32 taskID
UINT32 stackSize
UINTPTR topOfStack
UINT16 taskStatus
UINT16 usTaskPrio
Definition: los_task.h:505
UINTPTR auwArgs[4]
Definition: los_task.h:507
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
UINT32 processID
进程ID
Definition: los_task.h:516
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UINT32 uwResved
Definition: los_task.h:513
if(tv==NULL)
Definition: time.c:430