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 /** ThreadX Component                                                     */
16 /**                                                                       */
17 /**   Thread                                                              */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 #define TX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "tx_api.h"
29 #include "tx_thread.h"
30 #include <stdio.h>
31 #include <unistd.h>
32 
33 
34 /* Prototype for new thread entry function.  */
35 
36 void *_tx_linux_thread_entry(void *ptr);
37 
38 
39 /**************************************************************************/
40 /*                                                                        */
41 /*  FUNCTION                                               RELEASE        */
42 /*                                                                        */
43 /*    _tx_thread_stack_build                              Linux/GNU       */
44 /*                                                           6.1          */
45 /*  AUTHOR                                                                */
46 /*                                                                        */
47 /*    William E. Lamie, Microsoft Corporation                             */
48 /*                                                                        */
49 /*  DESCRIPTION                                                           */
50 /*                                                                        */
51 /*    This function builds a stack frame on the supplied thread's stack.  */
52 /*    The stack frame results in a fake interrupt return to the supplied  */
53 /*    function pointer.                                                   */
54 /*                                                                        */
55 /*  INPUT                                                                 */
56 /*                                                                        */
57 /*    thread_ptr                            Pointer to thread control blk */
58 /*    function_ptr                          Pointer to return function    */
59 /*                                                                        */
60 /*  OUTPUT                                                                */
61 /*                                                                        */
62 /*    None                                                                */
63 /*                                                                        */
64 /*  CALLS                                                                 */
65 /*                                                                        */
66 /*    pthread_create                                                      */
67 /*    pthread_setschedparam                                               */
68 /*    _tx_linux_thread_suspend                                            */
69 /*    sem_init                                                            */
70 /*    printf                                                              */
71 /*    _tx_linux_thread_resume                                             */
72 /*                                                                        */
73 /*  CALLED BY                                                             */
74 /*                                                                        */
75 /*    _tx_thread_create                     Create thread service         */
76 /*    _tx_thread_reset                      Reset thread service          */
77 /*                                                                        */
78 /*  RELEASE HISTORY                                                       */
79 /*                                                                        */
80 /*    DATE              NAME                      DESCRIPTION             */
81 /*                                                                        */
82 /*  09-30-2020     William E. Lamie         Initial Version 6.1           */
83 /*                                                                        */
84 /**************************************************************************/
_tx_thread_stack_build(TX_THREAD * thread_ptr,VOID (* function_ptr)(VOID))85 VOID   _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
86 {
87 struct sched_param sp;
88 
89     (VOID)function_ptr;
90 
91     /* Create the run semaphore for the thread.  This will allow the scheduler
92        control over when the thread actually runs.  */
93     if(sem_init(&thread_ptr -> tx_thread_linux_thread_run_semaphore, 0, 0))
94     {
95 
96         /* Display an error message.  */
97         printf("ThreadX Linux error creating thread running semaphore!\n");
98         while(1)
99         {
100         }
101     }
102 
103     /* Create a Linux thread for the application thread.  */
104     if(pthread_create(&thread_ptr -> tx_thread_linux_thread_id, NULL, _tx_linux_thread_entry, thread_ptr))
105     {
106 
107         /* Display an error message.  */
108         printf("ThreadX Linux error creating thread!\n");
109         while(1)
110         {
111         }
112     }
113 
114     /* Otherwise, we have a good thread create.  */
115     sp.sched_priority = TX_LINUX_PRIORITY_USER_THREAD;
116     pthread_setschedparam(thread_ptr -> tx_thread_linux_thread_id, SCHED_FIFO, &sp);
117 
118     /* Setup the thread suspension type to solicited thread suspension.
119        Pseudo interrupt handlers will suspend with this field set to 1.  */
120     thread_ptr -> tx_thread_linux_suspension_type =  0;
121 
122     /* Clear the disabled count that will keep track of the
123        tx_interrupt_control nesting.  */
124     thread_ptr -> tx_thread_linux_int_disabled_flag =  0;
125 
126     /* Setup a fake thread stack pointer.   */
127     thread_ptr -> tx_thread_stack_ptr =  (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);
128 
129     /* Clear the first word of the stack.  */
130     *(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) =  0;
131 }
132 
133 
_tx_linux_thread_entry(void * ptr)134 void *_tx_linux_thread_entry(void *ptr)
135 {
136 
137 TX_THREAD  *thread_ptr;
138 
139     /* Pickup the current thread pointer.  */
140     thread_ptr =  (TX_THREAD *) ptr;
141     _tx_linux_threadx_thread = 1;
142     nice(20);
143 
144     /* Now suspend the thread initially.  If the thread has already
145        been scheduled, this will return immediately.  */
146     tx_linux_sem_wait(&thread_ptr -> tx_thread_linux_thread_run_semaphore);
147     tx_linux_sem_post_nolock(&_tx_linux_semaphore);
148 
149     /* Call ThreadX thread entry point.  */
150     _tx_thread_shell_entry();
151 
152     return EXIT_SUCCESS;
153 }
154 
155