1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** POSIX wrapper for THREADX */
17 /** */
18 /** */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 /* Include necessary system files. */
24
25 #include "tx_api.h" /* Threadx API */
26 #include "pthread.h" /* Posix API */
27
28 /* this define will force declaration of the */
29 /* posix objects to happen in this file */
30 #define PX_OBJECT_INIT
31
32 #include "px_int.h" /* Posix helper functions */
33
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* is_posix_thread PORTABLE C */
40 /* 6.1.7 */
41 /* AUTHOR */
42 /* */
43 /* William E. Lamie, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* Verify that the control block belongs to a POSIX thread and not */
48 /* a ThreadX thread */
49 /* */
50 /* INPUT */
51 /* */
52 /* thread_ptr Pointer to a thread control block */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* TX_FALSE if not POSIX thread. TX_TRUE if POSIX thread. */
57 /* */
58 /* CALLS */
59 /* */
60 /* None */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Application Code */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
71 /* */
72 /**************************************************************************/
is_posix_thread(TX_THREAD * thread_ptr)73 static INT is_posix_thread(TX_THREAD *thread_ptr)
74 {
75 if (((POSIX_TCB *)thread_ptr < ptcb_pool) ||
76 ((POSIX_TCB *)thread_ptr > &ptcb_pool[PTHREAD_THREADS_MAX - 1]))
77 {
78 return TX_FALSE;
79 }
80 return TX_TRUE;
81 }
82
83
84 /**************************************************************************/
85 /* */
86 /* FUNCTION RELEASE */
87 /* */
88 /* posix_pthread_init PORTABLE C */
89 /* 6.1.7 */
90 /* AUTHOR */
91 /* */
92 /* William E. Lamie, Microsoft Corporation */
93 /* */
94 /* DESCRIPTION */
95 /* */
96 /* This function sets up / configures / initializes all the */
97 /* pthread Control Blocks that we define at compile-time in order to */
98 /* ensure that there is sufficient memory. */
99 /* */
100 /* INPUT */
101 /* */
102 /* None */
103 /* */
104 /* OUTPUT */
105 /* */
106 /* None */
107 /* */
108 /* CALLS */
109 /* */
110 /* posix_reset_pthread_t Reset a task control block */
111 /* */
112 /* CALLED BY */
113 /* */
114 /* Start-up code */
115 /* */
116 /* RELEASE HISTORY */
117 /* */
118 /* DATE NAME DESCRIPTION */
119 /* */
120 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
121 /* */
122 /**************************************************************************/
posix_pthread_init(VOID)123 VOID posix_pthread_init(VOID)
124 {
125
126 ULONG index;
127
128 /* Loop through array of TCBs and initialize each one. */
129 for (index = 0; index < PTHREAD_THREADS_MAX; index++)
130 {
131 posix_reset_pthread_t(&(ptcb_pool[index]));
132 }
133 }
134
135 /**************************************************************************/
136 /* */
137 /* FUNCTION RELEASE */
138 /* */
139 /* posix_reset_pthread_t PORTABLE C */
140 /* 6.1.7 */
141 /* AUTHOR */
142 /* */
143 /* William E. Lamie, Microsoft Corporation */
144 /* */
145 /* DESCRIPTION */
146 /* */
147 /* This function resets a pthread w/ default information. */
148 /* */
149 /* INPUT */
150 /* */
151 /* ptcb pthread control block pointer */
152 /* */
153 /* OUTPUT */
154 /* */
155 /* None */
156 /* */
157 /* CALLS */
158 /* */
159 /* None */
160 /* */
161 /* CALLED BY */
162 /* */
163 /* Start-up code */
164 /* */
165 /* RELEASE HISTORY */
166 /* */
167 /* DATE NAME DESCRIPTION */
168 /* */
169 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
170 /* */
171 /**************************************************************************/
posix_reset_pthread_t(POSIX_TCB * ptcb)172 VOID posix_reset_pthread_t (POSIX_TCB *ptcb)
173 {
174 /* Indicate this entry is not in use. */
175 ptcb->in_use = TX_FALSE;
176 }
177
178 /**************************************************************************/
179 /* */
180 /* FUNCTION RELEASE */
181 /* */
182 /* posix_copy_pthread_attr PORTABLE C */
183 /* 6.1.7 */
184 /* AUTHOR */
185 /* */
186 /* William E. Lamie, Microsoft Corporation */
187 /* */
188 /* DESCRIPTION */
189 /* */
190 /* This function copies pthread attributes from a pthread_attr object */
191 /* to a pthread TCB */
192 /* */
193 /* INPUT */
194 /* */
195 /* attr pthread attr object pointer */
196 /* pthread_ptr target pthread TCB */
197 /* */
198 /* OUTPUT */
199 /* */
200 /* None */
201 /* */
202 /* CALLS */
203 /* */
204 /* None */
205 /* */
206 /* CALLED BY */
207 /* */
208 /* Start-up code */
209 /* */
210 /* RELEASE HISTORY */
211 /* */
212 /* DATE NAME DESCRIPTION */
213 /* */
214 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
215 /* */
216 /**************************************************************************/
posix_copy_pthread_attr(POSIX_TCB * pthread_ptr,pthread_attr_t * attr)217 VOID posix_copy_pthread_attr(POSIX_TCB *pthread_ptr,pthread_attr_t *attr)
218 {
219
220 pthread_ptr->current_priority = attr->sched_attr.sched_priority ;
221 pthread_ptr->detach_state = attr->detach_state ;
222 pthread_ptr->inherit_sched = attr->inherit_sched ;
223 pthread_ptr->orig_priority = attr->sched_attr.sched_priority ;
224 pthread_ptr->sched_attr.sched_priority= attr->sched_attr.sched_priority ;
225 pthread_ptr->pthread_flags = attr->pthread_flags ;
226 pthread_ptr->sched_policy = attr->sched_policy;
227 pthread_ptr->stack_size = attr->stack_size ;
228 pthread_ptr->stack_address = attr->stack_address;
229
230 return;
231 }
232
233 /**************************************************************************/
234 /* */
235 /* FUNCTION RELEASE */
236 /* */
237 /* posix_allocate_pthread_t PORTABLE C */
238 /* 6.1.7 */
239 /* AUTHOR */
240 /* */
241 /* William E. Lamie, Microsoft Corporation */
242 /* */
243 /* DESCRIPTION */
244 /* */
245 /* This function attempts to allocate memory for a pthread stack and */
246 /* a POSIX pthread Control Block (PTCB). */
247 /* */
248 /* INPUT */
249 /* */
250 /* stack_size Requested task stack size */
251 /* tcb_ptr Pointer to tcb pointer */
252 /* */
253 /* OUTPUT */
254 /* */
255 /* Completion Status */
256 /* */
257 /* CALLS */
258 /* */
259 /* Nothing */
260 /* */
261 /* CALLED BY */
262 /* */
263 /* POSIX internal code */
264 /* */
265 /* RELEASE HISTORY */
266 /* */
267 /* DATE NAME DESCRIPTION */
268 /* */
269 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
270 /* */
271 /**************************************************************************/
posix_allocate_pthread_t(POSIX_TCB ** ptcb_ptr)272 INT posix_allocate_pthread_t(POSIX_TCB **ptcb_ptr)
273 {
274
275 POSIX_TCB *ptcb;
276 ULONG index;
277
278 /* Assume the worst. */
279 *ptcb_ptr = (POSIX_TCB *)0;
280
281 /* This next search is optimized for simplicity, not speed. */
282 for (index = 0, ptcb = ptcb_pool;
283 index < PTHREAD_THREADS_MAX;
284 index++, ptcb++)
285 {
286 /* Is this guy in use? If not, we can use it. */
287 if (ptcb->in_use == TX_FALSE)
288 {
289 /* This pTCB is now in use. */
290 ptcb->in_use = TX_TRUE;
291
292 /* Stop searching. */
293 break;
294 }
295 } /* for each POSIX Thread Control Block */
296
297 /* Did we search all pTCBs and come up empty? */
298 if (index == PTHREAD_THREADS_MAX)
299 {
300 /* No more pTCBs available - user configuration error. */
301 return(ERROR);
302 }
303 else
304 {
305
306 /* Make sure the signal handler information is cleared when the new TCB is allocated. */
307 memset(&(ptcb -> signals), 0, sizeof(signal_info));
308
309 /* Found one. */
310 *ptcb_ptr = ptcb;
311 }
312 return(OK);
313 }
314
315
316 /**************************************************************************/
317 /* */
318 /* FUNCTION RELEASE */
319 /* */
320 /* posix_thread_wrapper PORTABLE C */
321 /* 6.2.0 */
322 /* AUTHOR */
323 /* */
324 /* William E. Lamie, Microsoft Corporation */
325 /* */
326 /* DESCRIPTION */
327 /* */
328 /* Every thread that is modeling a ThreadX thread has this routine as */
329 /* its entry point.This routine simply calls the pthread entry routine */
330 /* with its sole argument passed in pthread-create(). */
331 /* */
332 /* The main purpose of this function is to mimic the pthread interface */
333 /* which allows 1 argument to be passed to the entry point of a thread */
334 /* */
335 /* INPUT */
336 /* */
337 /* pthread_ptr pthread control block pointer */
338 /* */
339 /* OUTPUT */
340 /* */
341 /* None */
342 /* */
343 /* CALLS */
344 /* */
345 /* *(pthread_start_routine) Application pthread entry */
346 /* */
347 /* CALLED BY */
348 /* */
349 /* POSIX only (internal) */
350 /* */
351 /* RELEASE HISTORY */
352 /* */
353 /* DATE NAME DESCRIPTION */
354 /* */
355 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
356 /* 10-31-2022 Scott Larson Add 64-bit support, */
357 /* resulting in version 6.2.0 */
358 /* */
359 /**************************************************************************/
posix_thread_wrapper(ULONG pthr_ptr)360 VOID posix_thread_wrapper(ULONG pthr_ptr)
361 {
362
363 POSIX_TCB *pthread_ptr;
364 VOID *value_ptr;
365
366 /* The input argument is really a pointer to the pthread's control block */
367 TX_THREAD_EXTENSION_PTR_GET(pthread_ptr, POSIX_TCB, pthr_ptr)
368
369 /* Invoke the pthread start routine with appropriate arguments */
370 value_ptr = (pthread_ptr->start_routine)((VOID *)pthread_ptr->entry_parameter);
371
372 /* In ThreadX, when a thread returns from its entry point, it enters the */
373 /* "completed" state, which is basically an infinite suspension. */
374 /* now use pthread_exit call to end this pthread */
375 pthread_exit(value_ptr);
376 }
377
378 /**************************************************************************/
379 /* */
380 /* FUNCTION RELEASE */
381 /* */
382 /* posix_thread2tcb PORTABLE C */
383 /* 6.1.7 */
384 /* AUTHOR */
385 /* */
386 /* William E. Lamie, Microsoft Corporation */
387 /* */
388 /* DESCRIPTION */
389 /* */
390 /* This function converts a ThreadX thread identifier into */
391 /* a posix pthread control block (TCB) */
392 /* */
393 /* INPUT */
394 /* */
395 /* thread_ptr Thread pointer */
396 /* */
397 /* OUTPUT */
398 /* */
399 /* pthread pthread Task control block */
400 /* */
401 /* CALLS */
402 /* */
403 /* posix_internal_error Internal error */
404 /* */
405 /* CALLED BY */
406 /* */
407 /* posix internal code */
408 /* */
409 /* RELEASE HISTORY */
410 /* */
411 /* DATE NAME DESCRIPTION */
412 /* */
413 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
414 /* */
415 /**************************************************************************/
posix_thread2tcb(TX_THREAD * thread_ptr)416 POSIX_TCB *posix_thread2tcb(TX_THREAD *thread_ptr)
417 {
418
419 POSIX_TCB *p_tcb;
420
421 /* Make sure we were called from a thread. */
422 if (!thread_ptr)
423 {
424 /* Not called from a thread - error! */
425 posix_internal_error(333);
426 }
427
428 /* Make sure thread is a POSIX thread else following case is illegal. */
429 if (!is_posix_thread(thread_ptr)) {
430 /* Not called from a POSIX thread - error! */
431 return NULL;
432 }
433
434 /* We can do this because the Thread information is intentionally */
435 /* located as the first field in the structure. */
436 p_tcb = (POSIX_TCB *)thread_ptr;
437
438 /* All done. */
439 return(p_tcb);
440 }
441
442 /**************************************************************************/
443 /* */
444 /* FUNCTION RELEASE */
445 /* */
446 /* posix_tcb2thread PORTABLE C */
447 /* 6.1.7 */
448 /* AUTHOR */
449 /* */
450 /* William E. Lamie, Microsoft Corporation */
451 /* */
452 /* DESCRIPTION */
453 /* */
454 /* This function converts a POSIX TCB into ThreadX thread */
455 /* */
456 /* */
457 /* INPUT */
458 /* */
459 /* pthread_ptr pthread TCB */
460 /* */
461 /* OUTPUT */
462 /* */
463 /* thread ThreadX thread */
464 /* */
465 /* CALLS */
466 /* */
467 /* posix_internal_error Internal error */
468 /* */
469 /* CALLED BY */
470 /* */
471 /* posix internal code */
472 /* */
473 /* RELEASE HISTORY */
474 /* */
475 /* DATE NAME DESCRIPTION */
476 /* */
477 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
478 /* */
479 /**************************************************************************/
posix_tcb2thread(POSIX_TCB * pthread_ptr)480 TX_THREAD *posix_tcb2thread (POSIX_TCB *pthread_ptr)
481 {
482
483 TX_THREAD *thread;
484
485 /* Make sure we don't have a NULL pointer. */
486 if (pthread_ptr)
487 {
488 /* Simply convert the TCB to a Thread via a cast */
489 thread = (&(pthread_ptr->thread_info ));
490 }
491 else
492 {
493 thread = ((TX_THREAD *)0);
494 }
495
496 return(thread);
497 }
498
499 /**************************************************************************/
500 /* */
501 /* FUNCTION RELEASE */
502 /* */
503 /* posix_thread2tid PORTABLE C */
504 /* 6.1.7 */
505 /* AUTHOR */
506 /* */
507 /* William E. Lamie, Microsoft Corporation */
508 /* */
509 /* DESCRIPTION */
510 /* */
511 /* This function converts a ThreadX thread identifier into */
512 /* posix thread ID */
513 /* */
514 /* INPUT */
515 /* */
516 /* thread_ptr Thread pointer */
517 /* */
518 /* OUTPUT */
519 /* */
520 /* thread_ID thread_ID */
521 /* */
522 /* CALLS */
523 /* */
524 /* posix_internal_error Internal error */
525 /* */
526 /* CALLED BY */
527 /* */
528 /* posix internal code */
529 /* */
530 /* RELEASE HISTORY */
531 /* */
532 /* DATE NAME DESCRIPTION */
533 /* */
534 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
535 /* */
536 /**************************************************************************/
posix_thread2tid(TX_THREAD * thread_ptr)537 pthread_t posix_thread2tid(TX_THREAD *thread_ptr)
538 {
539
540 pthread_t thread_ID;
541 POSIX_TCB *p_tcb;
542
543 /* Make sure we were called from a thread. */
544 if (!thread_ptr)
545 {
546 /* Not called from a thread - error! */
547 posix_internal_error(222);
548 }
549
550 /* Get the TCB for this pthread */
551
552 p_tcb = posix_thread2tcb(thread_ptr);
553 thread_ID = p_tcb->pthreadID;
554
555 /* All done. */
556 return(thread_ID);
557 }
558
559 /**************************************************************************/
560 /* */
561 /* FUNCTION RELEASE */
562 /* */
563 /* posix_tid2thread PORTABLE C */
564 /* 6.1.7 */
565 /* AUTHOR */
566 /* */
567 /* William E. Lamie, Microsoft Corporation */
568 /* */
569 /* DESCRIPTION */
570 /* */
571 /* This function converts a posix thread ID into a thread. */
572 /* */
573 /* INPUT */
574 /* */
575 /* tid Thread ID */
576 /* */
577 /* OUTPUT */
578 /* */
579 /* thread_ptr Thread pointer */
580 /* */
581 /* CALLS */
582 /* */
583 /* None */
584 /* */
585 /* CALLED BY */
586 /* */
587 /* posix internal code */
588 /* */
589 /* RELEASE HISTORY */
590 /* */
591 /* DATE NAME DESCRIPTION */
592 /* */
593 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
594 /* */
595 /**************************************************************************/
posix_tid2thread(pthread_t ptid)596 TX_THREAD *posix_tid2thread(pthread_t ptid)
597 {
598
599 TX_THREAD *thread;
600 POSIX_TCB *pthread;
601
602 /* Make sure we don't have a NULL TID. */
603 if (ptid)
604 {
605 /* convert the pthread ID to a pThread TCB */
606 pthread = posix_tid2tcb(ptid);
607 /* convert the pthread TCB to a pThread TCB */
608 thread= posix_tcb2thread(pthread);
609 }
610 else
611 {
612 thread = ((TX_THREAD *)0);
613 }
614 return(thread);
615 }
616
617 /**************************************************************************/
618 /* */
619 /* FUNCTION RELEASE */
620 /* */
621 /* posix_tid2tcb PORTABLE C */
622 /* 6.1.7 */
623 /* AUTHOR */
624 /* */
625 /* William E. Lamie, Microsoft Corporation */
626 /* */
627 /* DESCRIPTION */
628 /* */
629 /* This function converts a posix thread ID into a posix pthread TCB */
630 /* */
631 /* INPUT */
632 /* */
633 /* tid Thread ID */
634 /* */
635 /* OUTPUT */
636 /* */
637 /* pthread_ptr pthread pointer */
638 /* */
639 /* CALLS */
640 /* */
641 /* None */
642 /* */
643 /* CALLED BY */
644 /* */
645 /* posix internal code */
646 /* */
647 /* RELEASE HISTORY */
648 /* */
649 /* DATE NAME DESCRIPTION */
650 /* */
651 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
652 /* */
653 /**************************************************************************/
posix_tid2tcb(pthread_t ptid)654 POSIX_TCB *posix_tid2tcb(pthread_t ptid)
655 {
656
657 POSIX_TCB *pthread;
658
659 /* Make sure we don't have a NULL TID. */
660 if (ptid)
661 /* Simply convert the thread ID to a pthread TCB via a cast */
662 pthread = (POSIX_TCB *)ptid;
663 else
664 pthread = ((POSIX_TCB *)0);
665
666 return(pthread);
667 }
668
669 /**************************************************************************/
670 /* */
671 /* FUNCTION RELEASE */
672 /* */
673 /* posix_destroy_pthread PORTABLE C */
674 /* 6.2.0 */
675 /* AUTHOR */
676 /* */
677 /* William E. Lamie, Microsoft Corporation */
678 /* */
679 /* DESCRIPTION */
680 /* */
681 /* This function performs internal cleanup and housekeeping */
682 /* when a pthread exits. */
683 /* */
684 /* INPUT */
685 /* */
686 /* pthread_ptr pointer to TCB of the pthread */
687 /* to be deleted */
688 /* */
689 /* OUTPUT */
690 /* */
691 /* OK If successful */
692 /* ERROR If fails */
693 /* */
694 /* CALLS */
695 /* */
696 /* tx_queue_send Send to system mgr queue */
697 /* posix_internal_error Internal error handling */
698 /* */
699 /* CALLED BY */
700 /* */
701 /* posix internal code */
702 /* */
703 /* RELEASE HISTORY */
704 /* */
705 /* DATE NAME DESCRIPTION */
706 /* */
707 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
708 /* 10-31-2022 Scott Larson Add 64-bit support, */
709 /* resulting in version 6.2.0 */
710 /* */
711 /**************************************************************************/
posix_destroy_pthread(POSIX_TCB * pthread_ptr,VOID * value_ptr)712 VOID posix_destroy_pthread(POSIX_TCB *pthread_ptr, VOID *value_ptr)
713 {
714
715 ULONG request[WORK_REQ_SIZE];
716 UINT status;
717
718 /* Build the request. */
719
720 #ifdef TX_64_BIT
721 request[0] = (ULONG)((ALIGN_TYPE)pthread_ptr >> 32);
722 request[1] = (ULONG)((ALIGN_TYPE)pthread_ptr);
723 request[2] = (ULONG)((ALIGN_TYPE)value_ptr >> 32);
724 request[3] = (ULONG)((ALIGN_TYPE)value_ptr);
725 #else
726 request[0] = (ULONG)pthread_ptr;
727 request[1] = (ULONG)value_ptr;
728 #endif
729
730 /* Send a message to the SysMgr supervisor thread, asking it to delete */
731 /* the pthread. Since the SysMgr supervisor thread is the highest */
732 /* possible priority, this routine will be preempted when we */
733 /* post the message to the SysMgr's work queue. */
734
735 status = tx_queue_send(&posix_work_queue, request, TX_NO_WAIT);
736 /* This should always succeed. */
737 if (status != TX_SUCCESS)
738 {
739 posix_internal_error(1001);
740 }
741
742 /* Return the pthread's TCB to the pool of available TCB's. */
743 posix_reset_pthread_t(pthread_ptr);
744 }
745
746 /**************************************************************************/
747 /* */
748 /* FUNCTION RELEASE */
749 /* */
750 /* posix_do_pthread_delete PORTABLE C */
751 /* 6.1.7 */
752 /* AUTHOR */
753 /* */
754 /* William E. Lamie, Microsoft Corporation */
755 /* */
756 /* DESCRIPTION */
757 /* */
758 /* This function deletes the pthread and reclaims the stack memory. */
759 /* Also it resumes any pthread joined to this exiting pthread. */
760 /* */
761 /* INPUT */
762 /* */
763 /* pthread_ptr pointer to TCB of the pthread */
764 /* to be deleted */
765 /* */
766 /* OUTPUT */
767 /* */
768 /* OK If successful */
769 /* ERROR If fails */
770 /* */
771 /* CALLS */
772 /* */
773 /* tx_thread_terminate Terminate ThreadX thread */
774 /* tx_thread_delete Delete the ThreadX thread */
775 /* posix_memory_release Release the task's stack */
776 /* posix_free_tcb Free pthread control block */
777 /* */
778 /* CALLED BY */
779 /* */
780 /* posix internal code */
781 /* */
782 /* RELEASE HISTORY */
783 /* */
784 /* DATE NAME DESCRIPTION */
785 /* */
786 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
787 /* */
788 /**************************************************************************/
posix_do_pthread_delete(POSIX_TCB * pthread_ptr,VOID * value_ptr)789 VOID posix_do_pthread_delete(POSIX_TCB *pthread_ptr, VOID *value_ptr)
790 {
791
792 TX_INTERRUPT_SAVE_AREA
793
794 POSIX_TCB *joined_pthread_ptr;
795 TX_THREAD *thread_ptr,*thread1_ptr;
796 pthread_t joined_pthread_ID;
797 ULONG status;
798
799 TX_DISABLE
800 /* preserve the thread's return value regardless */
801 pthread_ptr->value_ptr = value_ptr;
802
803 if ( pthread_ptr->is_joined_by == TX_TRUE)
804 {
805 joined_pthread_ID = pthread_ptr->joined_by_pthreadID ;
806 joined_pthread_ptr = posix_tid2tcb(joined_pthread_ID);
807
808 joined_pthread_ptr->is_joined_to = TX_FALSE;
809 joined_pthread_ptr->joined_to_pthreadID =TX_FALSE;
810
811 thread_ptr = (TX_THREAD *)joined_pthread_ptr;
812
813 /* Now resume the suspended pthread joined to this pthread */
814 tx_thread_resume(thread_ptr);
815 }
816 /* Terminate the pthread's ThreadX thread. */
817 thread1_ptr = posix_tcb2thread(pthread_ptr);
818 status = tx_thread_terminate(thread1_ptr);
819 if (status != TX_SUCCESS)
820 {
821 posix_internal_error(2244);
822 }
823
824 /* Delete the pthread's ThreadX thread. */
825 status = tx_thread_delete(&(pthread_ptr->thread_info));
826 if (status != TX_SUCCESS)
827 {
828 posix_internal_error(2255);
829 }
830 /* Free the memory allocated for pthread's stack allocated from the posix heap */
831 /* if the memory was not from the posix heap this call has no effect */
832 /* it will be the user's responsibility to manage such memory */
833
834 posix_memory_release(pthread_ptr->stack_address);
835
836 /* Determine if this thread is NOT a signal handler thread. If this is the case,
837 delete the event flag group. */
838 if (pthread_ptr -> signals.signal_handler == FALSE)
839 {
840
841 /* Delete the event flag group. */
842 tx_event_flags_delete(&(pthread_ptr -> signals.signal_event_flags));
843 }
844
845 /* Return the pthread's TCB to the pool of available TCB's. */
846 pthread_ptr->in_use = TX_FALSE;
847
848 TX_RESTORE
849
850 /* All done. */
851 return;
852 }
853
854 /**************************************************************************/
855 /* */
856 /* FUNCTION RELEASE */
857 /* */
858 /* posix_set_pthread_errno PORTABLE C */
859 /* 6.1.7 */
860 /* AUTHOR */
861 /* */
862 /* William E. Lamie, Microsoft Corporation */
863 /* */
864 /* DESCRIPTION */
865 /* */
866 /* This function sets the pthread error number. */
867 /* Each pthread has got its very own erron number. */
868 /* */
869 /* INPUT */
870 /* */
871 /* errno_set error number to set */
872 /* */
873 /* */
874 /* OUTPUT */
875 /* */
876 /* OK Always return successful */
877 /* */
878 /* CALLS */
879 /* */
880 /* tx_thread_identify get calling ThreadX thread */
881 /* */
882 /* CALLED BY */
883 /* */
884 /* posix internal code */
885 /* */
886 /* RELEASE HISTORY */
887 /* */
888 /* DATE NAME DESCRIPTION */
889 /* */
890 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
891 /* */
892 /**************************************************************************/
posix_set_pthread_errno(ULONG errno_set)893 INT posix_set_pthread_errno(ULONG errno_set)
894 {
895
896 TX_THREAD *thread_ptr;
897 POSIX_TCB *pthread_ptr;
898
899 /* Get the thread identifier of the currently running thread */
900 thread_ptr = tx_thread_identify();
901 /* get posix TCB for this pthread */
902 pthread_ptr = (POSIX_TCB *)thread_ptr;
903 /* Set the error number */
904 pthread_ptr->perrno = errno_set;
905
906 /* Always return success!*/
907 return(OK);
908 }
909
910 /**************************************************************************/
911 /* */
912 /* FUNCTION RELEASE */
913 /* */
914 /* posix_get_pthread_errno PORTABLE C */
915 /* 6.1.7 */
916 /* AUTHOR */
917 /* */
918 /* William E. Lamie, Microsoft Corporation */
919 /* */
920 /* DESCRIPTION */
921 /* */
922 /* This function gets the erron number for a pthread. */
923 /* Each pthread has got its very own erron number. */
924 /* */
925 /* INPUT */
926 /* */
927 /* ptid pthread id */
928 /* */
929 /* */
930 /* OUTPUT */
931 /* */
932 /* error_number error number for the pthread */
933 /* ERROR In case of any error */
934 /* */
935 /* CALLS */
936 /* */
937 /* tx_thread_identify get calling ThreadX thread */
938 /* */
939 /* CALLED BY */
940 /* */
941 /* posix internal code */
942 /* */
943 /* RELEASE HISTORY */
944 /* */
945 /* DATE NAME DESCRIPTION */
946 /* */
947 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
948 /* */
949 /**************************************************************************/
posix_get_pthread_errno(pthread_t ptid)950 INT posix_get_pthread_errno(pthread_t ptid)
951 {
952
953 TX_INTERRUPT_SAVE_AREA
954
955 INT error_number;
956 POSIX_TCB *pthread_ptr;
957
958 TX_DISABLE
959
960 /* Get the POSIX pthread structure pointer for the ptid */
961 pthread_ptr = posix_tid2tcb(ptid);
962 /* Check whether we got NULL pointer */
963 if (pthread_ptr)
964 /* Retrive the stored error number for this pthread */
965 error_number = pthread_ptr->perrno;
966 else
967 error_number = ERROR;
968
969 TX_RESTORE
970 return(error_number);
971 }
972