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