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