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 /**   Port Specific                                                       */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  PORT SPECIFIC C INFORMATION                            RELEASE        */
27 /*                                                                        */
28 /*    tx_port.h                                         SMP/Linux/GCC     */
29 /*                                                           6.1.9        */
30 /*                                                                        */
31 /*  AUTHOR                                                                */
32 /*                                                                        */
33 /*    William E. Lamie, Microsoft Corporation                             */
34 /*                                                                        */
35 /*  DESCRIPTION                                                           */
36 /*                                                                        */
37 /*    This file contains data type definitions that make the ThreadX      */
38 /*    real-time kernel function identically on a variety of different     */
39 /*    processor architectures.  For example, the size or number of bits   */
40 /*    in an "int" data type vary between microprocessor architectures and */
41 /*    even C compilers for the same microprocessor.  ThreadX does not     */
42 /*    directly use native C data types.  Instead, ThreadX creates its     */
43 /*    own special types that can be mapped to actual data types by this   */
44 /*    file to guarantee consistency in the interface and functionality.   */
45 /*                                                                        */
46 /*  RELEASE HISTORY                                                       */
47 /*                                                                        */
48 /*    DATE              NAME                      DESCRIPTION             */
49 /*                                                                        */
50 /*  09-30-2020     William E. Lamie         Initial Version 6.1           */
51 /*  04-02-2021     Bhupendra Naphade        Modified comment(s),updated   */
52 /*                                            macro definition,           */
53 /*                                            resulting in version 6.1.6  */
54 /*  10-15-2021     William E. Lamie         Modified comment(s), added    */
55 /*                                            symbol ULONG64_DEFINED,     */
56 /*                                            resulting in version 6.1.9  */
57 /*                                                                        */
58 /**************************************************************************/
59 
60 #ifndef TX_PORT_H
61 #define TX_PORT_H
62 
63 
64 
65 /************* Define ThreadX SMP constants.  *************/
66 
67 #define TX_DISABLE_INLINE
68 
69 
70 /* Define the ThreadX SMP maximum number of cores.  */
71 
72 #ifndef TX_THREAD_SMP_MAX_CORES
73 #define TX_THREAD_SMP_MAX_CORES                 4
74 #endif
75 
76 
77 
78 /* Define the ThreadX SMP core mask. */
79 
80 #ifndef TX_THREAD_SMP_CORE_MASK
81 #define TX_THREAD_SMP_CORE_MASK                 0xF            /* Where bit 0 represents Core 0, bit 1 represents Core 1, etc.  */
82 #endif
83 
84 /* Define dynamic number of cores option.  When commented out, the number of cores is static.  */
85 
86 /* #define TX_THREAD_SMP_DYNAMIC_CORE_MAX  */
87 
88 
89 /* Define ThreadX SMP initialization macro.  */
90 
91 #define TX_PORT_SPECIFIC_PRE_INITIALIZATION
92 
93 
94 /* Enable the inter-core interrupt logic.  */
95 
96 #define TX_THREAD_SMP_INTER_CORE_INTERRUPT
97 
98 
99 /* Determine if there is customer-specific wakeup logic needed.  */
100 
101 #ifdef TX_THREAD_SMP_WAKEUP_LOGIC
102 
103 /* Include customer-specific wakeup code.  */
104 
105 #include "tx_thread_smp_core_wakeup.h"
106 #else
107 
108 #ifdef TX_THREAD_SMP_DEFAULT_WAKEUP_LOGIC
109 
110 /* Default wakeup code.  */
111 #define TX_THREAD_SMP_WAKEUP_LOGIC
112 #define TX_THREAD_SMP_WAKEUP(i)                _tx_thread_smp_core_preempt(i)
113 #endif
114 #endif
115 
116 
117 /* Ensure that the in-line resume/suspend define is not allowed.  */
118 
119 #ifdef TX_INLINE_THREAD_RESUME_SUSPEND
120 #undef TX_INLINE_THREAD_RESUME_SUSPEND
121 #endif
122 
123 
124 /* Overide inline keyword.  */
125 
126 #define INLINE_DECLARE  __inline
127 
128 
129 /************* End ThreadX SMP constants.  *************/
130 
131 
132 /* Determine if the optional ThreadX user define file should be used.  */
133 
134 #ifdef TX_INCLUDE_USER_DEFINE_FILE
135 
136 
137 /* Yes, include the user defines in tx_user.h. The defines in this file may
138    alternately be defined on the command line.  */
139 
140 #include "tx_user.h"
141 #endif
142 
143 
144 /* Define compiler library include files.  */
145 
146 #include <stdlib.h>
147 #include <string.h>
148 #include <stdint.h>
149 #ifndef __USE_POSIX199309
150 #define __USE_POSIX199309
151 #include <pthread.h>
152 #include <semaphore.h>
153 #include <time.h>
154 #undef __USE_POSIX199309
155 #else /* __USE_POSIX199309 */
156 #include <pthread.h>
157 #include <semaphore.h>
158 #include <time.h>
159 #endif /* __USE_POSIX199309 */
160 
161 
162 /* Define ThreadX basic types for this port.  */
163 
164 typedef void                                    VOID;
165 typedef char                                    CHAR;
166 typedef unsigned char                           UCHAR;
167 typedef int                                     INT;
168 typedef unsigned int                            UINT;
169 typedef long                                    LONG;
170 typedef unsigned long                           ULONG;
171 typedef short                                   SHORT;
172 typedef unsigned short                          USHORT;
173 typedef uint64_t                                ULONG64;
174 #define ULONG64_DEFINED
175 
176 
177 /* Define automated coverage test extensions...  These are required for the
178    ThreadX regression test.  */
179 
180 typedef unsigned int    TEST_FLAG;
181 extern TEST_FLAG        threadx_byte_allocate_loop_test;
182 extern TEST_FLAG        threadx_byte_release_loop_test;
183 extern TEST_FLAG        threadx_mutex_suspension_put_test;
184 extern TEST_FLAG        threadx_mutex_suspension_priority_test;
185 #ifndef TX_TIMER_PROCESS_IN_ISR
186 extern TEST_FLAG        threadx_delete_timer_thread;
187 #endif
188 
189 extern void             abort_and_resume_byte_allocating_thread(void);
190 extern void             abort_all_threads_suspended_on_mutex(void);
191 extern void             suspend_lowest_priority(void);
192 #ifndef TX_TIMER_PROCESS_IN_ISR
193 extern void             delete_timer_thread(void);
194 #endif
195 extern TEST_FLAG        test_stack_analyze_flag;
196 extern TEST_FLAG        test_initialize_flag;
197 extern TEST_FLAG        test_forced_mutex_timeout;
198 extern UINT             mutex_priority_change_extension_selection;
199 extern UINT             priority_change_extension_selection;
200 
201 
202 #ifdef TX_REGRESSION_TEST
203 
204 /* Define extension macros for automated coverage tests.  */
205 
206 
207 #define TX_PORT_SPECIFIC_MEMORY_SYNCHRONIZATION other_core_status =  other_core_status + _tx_thread_system_state[0]; \
208                                                 _tx_thread_system_state[0] =  0;
209 
210 
211 #define TX_BYTE_ALLOCATE_EXTENSION              if (threadx_byte_allocate_loop_test == ((TEST_FLAG) 1))         \
212                                                 {                                                               \
213                                                     pool_ptr -> tx_byte_pool_owner =  TX_NULL;                  \
214                                                     threadx_byte_allocate_loop_test = ((TEST_FLAG) 0);          \
215                                                 }
216 
217 #define TX_BYTE_RELEASE_EXTENSION               if (threadx_byte_release_loop_test == ((TEST_FLAG) 1))          \
218                                                 {                                                               \
219                                                     threadx_byte_release_loop_test = ((TEST_FLAG) 0);           \
220                                                     abort_and_resume_byte_allocating_thread();                  \
221                                                 }
222 
223 #define TX_MUTEX_PUT_EXTENSION_1                if (threadx_mutex_suspension_put_test == ((TEST_FLAG) 1))       \
224                                                 {                                                               \
225                                                     threadx_mutex_suspension_put_test = ((TEST_FLAG) 0);        \
226                                                     abort_all_threads_suspended_on_mutex();                     \
227                                                 }
228 
229 
230 #define TX_MUTEX_PUT_EXTENSION_2                if (test_forced_mutex_timeout == ((TEST_FLAG) 1))               \
231                                                 {                                                               \
232                                                     test_forced_mutex_timeout = ((TEST_FLAG) 0);                \
233                                                     _tx_thread_wait_abort(mutex_ptr -> tx_mutex_suspension_list); \
234                                                 }
235 
236 
237 #define TX_MUTEX_PRIORITY_CHANGE_EXTENSION      if (threadx_mutex_suspension_priority_test == ((TEST_FLAG) 1))  \
238                                                 {                                                               \
239                                                     threadx_mutex_suspension_priority_test = ((TEST_FLAG) 0);   \
240                                                     if (mutex_priority_change_extension_selection == 2)         \
241                                                         original_priority = new_priority;                       \
242                                                     if (mutex_priority_change_extension_selection == 3)         \
243                                                         original_pt_thread =  thread_ptr;                       \
244                                                     if (mutex_priority_change_extension_selection == 4)         \
245                                                     {                                                           \
246                                                         execute_ptr =  thread_ptr;                              \
247                                                         _tx_thread_preemption__threshold_scheduled = TX_NULL;   \
248                                                     }                                                           \
249                                                     suspend_lowest_priority();                                  \
250                                                 }
251 
252 #define TX_THREAD_PRIORITY_CHANGE_EXTENSION     if (priority_change_extension_selection != ((TEST_FLAG) 0))     \
253                                                 {                                                               \
254                                                     if (priority_change_extension_selection == 1)               \
255                                                         thread_ptr -> tx_thread_smp_core_mapped =  TX_THREAD_SMP_MAX_CORES; \
256                                                     else if (priority_change_extension_selection == 2)          \
257                                                     {                                                           \
258                                                         original_priority =  new_priority;                      \
259                                                         _tx_thread_execute_ptr[0] =  TX_NULL;                   \
260                                                     }                                                           \
261                                                     else if (priority_change_extension_selection == 3)          \
262                                                     {                                                           \
263                                                         original_pt_thread =  thread_ptr;                       \
264                                                     }                                                           \
265                                                     else                                                        \
266                                                     {                                                           \
267                                                         _tx_thread_preemption__threshold_scheduled = TX_NULL;   \
268                                                     }                                                           \
269                                                     priority_change_extension_selection =  0;                   \
270                                                 }
271 
272 
273 #ifndef TX_TIMER_PROCESS_IN_ISR
274 
275 #define TX_TIMER_INITIALIZE_EXTENSION(a)        if (threadx_delete_timer_thread == ((TEST_FLAG) 1))             \
276                                                 {                                                               \
277                                                     threadx_delete_timer_thread = ((TEST_FLAG) 0);              \
278                                                     delete_timer_thread();                                      \
279                                                     (a) =  ((UINT) 1);                                          \
280                                                 }
281 
282 #endif
283 
284 #define TX_THREAD_STACK_ANALYZE_EXTENSION       if (test_stack_analyze_flag == ((TEST_FLAG) 1))                 \
285                                                 {                                                               \
286                                                     thread_ptr -> tx_thread_id =  ((TEST_FLAG) 0);              \
287                                                     test_stack_analyze_flag =     ((TEST_FLAG) 0);              \
288                                                 }                                                               \
289                                                 else if (test_stack_analyze_flag == ((TEST_FLAG) 2))            \
290                                                 {                                                               \
291                                                     stack_ptr =  thread_ptr -> tx_thread_stack_start;           \
292                                                     test_stack_analyze_flag =     ((TEST_FLAG) 0);              \
293                                                 }                                                               \
294                                                 else if (test_stack_analyze_flag == ((TEST_FLAG) 3))            \
295                                                 {                                                               \
296                                                     *stack_ptr =  TX_STACK_FILL;                                \
297                                                     test_stack_analyze_flag =     ((TEST_FLAG) 0);              \
298                                                 }                                                               \
299                                                 else                                                            \
300                                                 {                                                               \
301                                                     test_stack_analyze_flag =     ((TEST_FLAG) 0);              \
302                                                 }
303 
304 #define TX_INITIALIZE_KERNEL_ENTER_EXTENSION    if (test_initialize_flag == ((TEST_FLAG) 1))                    \
305                                                 {                                                               \
306                                                     test_initialize_flag =  ((TEST_FLAG) 0);                    \
307                                                     return;                                                     \
308                                                 }
309 
310 #endif
311 
312 
313 /* Add Linux debug insert prototype.  */
314 
315 void    _tx_linux_debug_entry_insert(char *action, char *file, unsigned long line);
316 
317 #ifndef TX_LINUX_DEBUG_ENABLE
318 
319 /* If Linux debug is not enabled, turn logging into white-space.  */
320 
321 #define _tx_linux_debug_entry_insert(a, b, c)
322 
323 #endif
324 
325 
326 
327 /* Define the TX_MEMSET macro to remove library reference.  */
328 
329 #ifndef TX_MISRA_ENABLE
330 #define TX_MEMSET(a,b,c)                        {                                       \
331                                                 UCHAR *ptr;                             \
332                                                 UCHAR value;                            \
333                                                 UINT  i, size;                          \
334                                                     ptr =    (UCHAR *) ((VOID *) a);    \
335                                                     value =  (UCHAR) b;                 \
336                                                     size =   (UINT) c;                  \
337                                                     for (i = 0; i < size; i++)          \
338                                                     {                                   \
339                                                         *ptr++ =  value;                \
340                                                     }                                   \
341                                                 }
342 #endif
343 
344 
345 /* Define the priority levels for ThreadX.  Legal values range
346    from 32 to 1024 and MUST be evenly divisible by 32.  */
347 
348 #ifndef TX_MAX_PRIORITIES
349 #define TX_MAX_PRIORITIES                       32
350 #endif
351 
352 
353 /* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
354    thread creation is less than this value, the thread create call will return an error.  */
355 
356 #ifndef TX_MINIMUM_STACK
357 #define TX_MINIMUM_STACK                        200         /* Minimum stack size for this port */
358 #endif
359 
360 
361 /* Define the system timer thread's default stack size and priority.  These are only applicable
362    if TX_TIMER_PROCESS_IN_ISR is not defined.  */
363 
364 #ifndef TX_TIMER_THREAD_STACK_SIZE
365 #define TX_TIMER_THREAD_STACK_SIZE              400         /* Default timer thread stack size - Not used in Linux port!  */
366 #endif
367 
368 #ifndef TX_TIMER_THREAD_PRIORITY
369 #define TX_TIMER_THREAD_PRIORITY                0           /* Default timer thread priority    */
370 #endif
371 
372 
373 /* Define various constants for the ThreadX  port.  */
374 
375 #define TX_INT_DISABLE                          1           /* Disable interrupts               */
376 #define TX_INT_ENABLE                           0           /* Enable interrupts                */
377 
378 
379 /* Define the clock source for trace event entry time stamp. The following two item are port specific.
380    For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
381    source constants would be:
382 
383 #define TX_TRACE_TIME_SOURCE                    *((ULONG *) 0x0a800024)
384 #define TX_TRACE_TIME_MASK                      0x0000FFFFUL
385 
386 */
387 
388 #ifndef TX_MISRA_ENABLE
389 #ifndef TX_TRACE_TIME_SOURCE
390 #define TX_TRACE_TIME_SOURCE                    ((ULONG) (_tx_linux_time_stamp.tv_nsec))
391 #endif
392 #else
393 ULONG   _tx_misra_time_stamp_get(VOID);
394 #define TX_TRACE_TIME_SOURCE                    _tx_misra_time_stamp_get()
395 #endif
396 
397 #ifndef TX_TRACE_TIME_MASK
398 #define TX_TRACE_TIME_MASK                      0xFFFFFFFFUL
399 #endif
400 
401 
402 /* Define the port-specific trace extension to pickup the Windows timer.  */
403 
404 #define TX_TRACE_PORT_EXTENSION                 clock_gettime(CLOCK_REALTIME, &_tx_linux_time_stamp);
405 
406 
407 /* Define the port specific options for the _tx_build_options variable. This variable indicates
408    how the ThreadX library was built.  */
409 
410 #define TX_PORT_SPECIFIC_BUILD_OPTIONS          0
411 
412 
413 /* Define the in-line initialization constant so that modules with in-line
414    initialization capabilities can prevent their initialization from being
415    a function call.  */
416 
417 #ifdef TX_MISRA_ENABLE
418 #define TX_DISABLE_INLINE
419 #else
420 #define TX_INLINE_INITIALIZATION
421 #endif
422 
423 
424 /* Define the Linux-specific initialization code that is expanded in the generic source.  */
425 
426 void    _tx_initialize_start_interrupts(void);
427 
428 
429 #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION                       _tx_initialize_start_interrupts();                  \
430                                                                             {                                                   \
431                                                                             UINT k;                                             \
432                                                                                 for (k = 1; k < TX_THREAD_SMP_MAX_CORES; k++)   \
433                                                                                 {                                               \
434                                                                                     _tx_thread_system_state[k] =  0;            \
435                                                                                 }                                               \
436                                                                             }
437 
438 /* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
439    disabled. When the following is defined, ThreadX thread stack checking is enabled.  If stack
440    checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
441    define is negated, thereby forcing the stack fill which is necessary for the stack checking
442    logic.  */
443 
444 #ifndef TX_MISRA_ENABLE
445 #ifdef TX_ENABLE_STACK_CHECKING
446 #undef TX_DISABLE_STACK_FILLING
447 #endif
448 #endif
449 
450 
451 /* Define the TX_THREAD control block extensions for this port. The main reason
452    for the multiple macros is so that backward compatibility can be maintained with
453    existing ThreadX kernel awareness modules.  */
454 
455 #define TX_THREAD_EXTENSION_0                                               pthread_t   tx_thread_linux_thread_id; \
456                                                                             sem_t       tx_thread_linux_thread_run_semaphore; \
457                                                                             UINT        tx_thread_linux_suspension_type; \
458                                                                             UINT        tx_thread_linux_mutex_access; \
459                                                                             UINT        tx_thread_linux_int_disabled_flag; \
460                                                                             UINT        tx_thread_linux_deferred_preempt; \
461                                                                             UINT        tx_thread_linux_virtual_core;
462 
463 #define TX_THREAD_EXTENSION_1
464 #define TX_THREAD_EXTENSION_2
465 #define TX_THREAD_EXTENSION_3
466 
467 
468 /* Define the port extensions of the remaining ThreadX objects.  */
469 
470 #define TX_BLOCK_POOL_EXTENSION
471 #define TX_BYTE_POOL_EXTENSION
472 #define TX_EVENT_FLAGS_GROUP_EXTENSION
473 #define TX_MUTEX_EXTENSION
474 #define TX_QUEUE_EXTENSION
475 #define TX_SEMAPHORE_EXTENSION
476 #define TX_TIMER_EXTENSION
477 
478 
479 /* Define the user extension field of the thread control block.  Nothing
480    additional is needed for this port so it is defined as white space.  */
481 
482 #ifndef TX_THREAD_USER_EXTENSION
483 #define TX_THREAD_USER_EXTENSION
484 #endif
485 
486 
487 /* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
488    tx_thread_shell_entry, and tx_thread_terminate.  */
489 
490 
491 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)
492 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)
493 #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
494 #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
495 
496 
497 /* Define the ThreadX object creation extensions for the remaining objects.  */
498 
499 #define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
500 #define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
501 #define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
502 #define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
503 #define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
504 #define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
505 #define TX_TIMER_CREATE_EXTENSION(timer_ptr)
506 
507 
508 /* Define the Linux mutex data structure.  */
509 
510 typedef struct
511 {
512     pthread_mutex_t tx_linux_mutex;
513     pthread_t       tx_linux_mutex_owner;
514     ULONG           tx_linux_mutex_nested_count;
515 } TX_LINUX_MUTEX;
516 
517 
518 /* Define Linux-specific critical section APIs.  */
519 
520 void _tx_linux_mutex_obtain(TX_LINUX_MUTEX *mutex);
521 void _tx_linux_mutex_release(TX_LINUX_MUTEX *mutex);
522 void _tx_linux_mutex_release_all(TX_LINUX_MUTEX *mutex);
523 
524 typedef struct TX_THREAD_STRUCT TX_THREAD;
525 
526 /* Define post completion processing for tx_thread_delete, so that the Linux thread resources are properly removed.  */
527 
528 void _tx_thread_delete_port_completion(TX_THREAD *thread_ptr, UINT tx_interrupt_save);
529 #define TX_THREAD_DELETE_PORT_COMPLETION(thread_ptr) _tx_thread_delete_port_completion(thread_ptr, tx_interrupt_save);
530 
531 
532 /* Define post completion processing for tx_thread_reset, so that the Linux thread resources are properly removed.  */
533 
534 void _tx_thread_reset_port_completion(TX_THREAD *thread_ptr, UINT tx_interrupt_save);
535 #define TX_THREAD_RESET_PORT_COMPLETION(thread_ptr) _tx_thread_reset_port_completion(thread_ptr, tx_interrupt_save);
536 
537 
538 /************* Define ThreadX SMP data types and function prototypes.  *************/
539 
540 struct TX_THREAD_STRUCT;
541 
542 
543 /* Define the ThreadX SMP protection structure.   */
544 
545 typedef struct TX_THREAD_SMP_PROTECT_STRUCT
546 {
547     ULONG                   tx_thread_smp_protect_in_force;
548     struct TX_THREAD_STRUCT *tx_thread_smp_protect_thread;
549     ULONG                   tx_thread_smp_protect_core;
550     ULONG                   tx_thread_smp_protect_count;
551     pthread_t               tx_thread_smp_protect_linux_thread_id;
552 } TX_THREAD_SMP_PROTECT;
553 
554 
555 /* Define the virtual core structure for ThreadX SMP Linux.  This is where we keep the mapping of the core to
556    the actual thread running.  All ISRs are assumed to be running on core 0 for Linux.  */
557 
558 typedef struct TX_THREAD_SMP_CORE_MAPPING_STRUCT
559 {
560     pthread_t               tx_thread_smp_core_mapping_linux_thread_id;
561     struct TX_THREAD_STRUCT *tx_thread_smp_core_mapping_thread;
562 } TX_THREAD_SMP_CORE_MAPPING;
563 
564 
565 /* Define ThreadX SMP low-level assembly routines.   */
566 
567 struct TX_THREAD_STRUCT *   _tx_thread_smp_current_thread_get(void);
568 UINT                        _tx_thread_smp_protect(void);
569 void                        _tx_thread_smp_unprotect(UINT interrupt_save);
570 ULONG                       _tx_thread_smp_current_state_get(void);
571 ULONG                       _tx_thread_smp_time_get(void);
572 
573 
574 /* Determine if SMP Debug is selected.  If so, the function prototype is setup. Otherwise, the debug call is
575    simply mapped to whitespace.  */
576 
577 #ifdef TX_THREAD_SMP_DEBUG_ENABLE
578 void                        _tx_thread_smp_debug_entry_insert(ULONG id, ULONG suspend, VOID *thread_ptr);
579 #else
580 #define                     _tx_thread_smp_debug_entry_insert(a, b, c)
581 #endif
582 
583 
584 /* Define the get core ID macro.  */
585 
586 #define TX_SMP_CORE_ID                          _tx_thread_smp_core_get()
587 
588 
589 
590 
591 /* Define the ThreadX object deletion extensions for the remaining objects.  */
592 
593 #define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
594 #define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
595 #define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
596 #define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
597 #define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
598 #define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
599 #define TX_TIMER_DELETE_EXTENSION(timer_ptr)
600 
601 
602 /* Define ThreadX interrupt lockout and restore macros for protection on
603    access of critical kernel information.  The restore interrupt macro must
604    restore the interrupt posture of the running thread prior to the value
605    present prior to the disable macro.  In most cases, the save area macro
606    is used to define a local function save area for the disable and restore
607    macros.  */
608 
609 #define TX_INTERRUPT_SAVE_AREA                  UINT tx_interrupt_save;
610 
611 #define TX_DISABLE                              tx_interrupt_save =  _tx_thread_smp_protect();
612 #define TX_RESTORE                              _tx_thread_smp_unprotect(tx_interrupt_save);
613 
614 
615 /************* End ThreadX SMP data type and function prototype definitions.  *************/
616 
617 
618 #define tx_linux_sem_post(p)                sem_post(p)
619 #define tx_linux_sem_wait(p)                sem_wait(p)
620 #define tx_linux_sem_timedwait(p, t)        sem_timedwait(p, t)
621 
622 
623 /* Define the interrupt lockout macros for each ThreadX object.  */
624 
625 #define TX_BLOCK_POOL_DISABLE               TX_DISABLE
626 #define TX_BYTE_POOL_DISABLE                TX_DISABLE
627 #define TX_EVENT_FLAGS_GROUP_DISABLE        TX_DISABLE
628 #define TX_MUTEX_DISABLE                    TX_DISABLE
629 #define TX_QUEUE_DISABLE                    TX_DISABLE
630 #define TX_SEMAPHORE_DISABLE                TX_DISABLE
631 
632 
633 /* Define the version ID of ThreadX.  This may be utilized by the application.  */
634 
635 #ifdef TX_THREAD_INIT
636 CHAR                            _tx_version_id[] =
637                                     "Copyright (c) Microsoft Corporation. All rights reserved.  *  ThreadX SMP/Linux/gcc Version 6.2.1 *";
638 #else
639 extern  CHAR                    _tx_version_id[];
640 #endif
641 
642 
643 /* Define externals for the Linux port of ThreadX.  */
644 
645 extern TX_LINUX_MUTEX                           _tx_linux_mutex;
646 extern sem_t                                    _tx_linux_scheduler_semaphore;
647 extern pthread_t                                _tx_linux_scheduler_id;
648 extern ULONG                                    _tx_linux_global_int_disabled_flag;
649 extern struct timespec                          _tx_linux_time_stamp;
650 extern ULONG                                    _tx_linux_system_error;
651 extern TX_THREAD_SMP_CORE_MAPPING               _tx_linux_virtual_cores[TX_THREAD_SMP_MAX_CORES];
652 extern __thread int                             _tx_linux_threadx_thread;
653 
654 /* Define functions for linux thread. */
655 void    _tx_linux_thread_suspend(pthread_t thread_id);
656 void    _tx_linux_thread_resume(pthread_t thread_id);
657 void    _tx_linux_thread_init();
658 void    _tx_linux_thread_sleep(long ns);
659 
660 #ifndef TX_LINUX_MEMORY_SIZE
661 #define TX_LINUX_MEMORY_SIZE                    100000
662 #endif
663 
664 #ifndef TX_TIMER_TICKS_PER_SECOND
665 #define TX_TIMER_TICKS_PER_SECOND               100UL
666 #endif
667 
668 #ifndef TX_LINUX_THREAD_STACK_SIZE
669 #define TX_LINUX_THREAD_STACK_SIZE              65536
670 #endif
671 
672 /* Define priorities of pthreads. */
673 #define TX_LINUX_PRIORITY_SCHEDULE              (3)
674 #define TX_LINUX_PRIORITY_ISR                   (2)
675 #define TX_LINUX_PRIORITY_USER_THREAD           (1)
676 
677 #endif
678 
679 
680 
681 
682 
683 
684 
685