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