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