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 /**   ThreadX Component                                                   */
16 /**                                                                       */
17 /**   POSIX Compliancy Wrapper (POSIX)                                    */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 /**************************************************************************/
23 /*                                                                        */
24 /*  EKP DEFINITIONS                                        RELEASE        */
25 /*                                                                        */
26 /*    tx_posix.h                                          PORTABLE C      */
27 /*                                                           6.2.0        */
28 /*  AUTHOR                                                                */
29 /*                                                                        */
30 /*    William E. Lamie, Microsoft Corporation                             */
31 /*                                                                        */
32 /*  DESCRIPTION                                                           */
33 /*                                                                        */
34 /*    This file defines the constants, structures, etc.needed to          */
35 /*    implement the Evacuation Kit for POSIX Users (POSIX)                */
36 /*                                                                        */
37 /*                                                                        */
38 /*  RELEASE HISTORY                                                       */
39 /*                                                                        */
40 /*    DATE              NAME                      DESCRIPTION             */
41 /*                                                                        */
42 /*  06-02-2021      William E. Lamie        Initial Version 6.1.7         */
43 /*  10-31-2022      Scott Larson            Update WORK_REQ_SIZE value,   */
44 /*                                            update pthread_t typedef,   */
45 /*                                            resulting in version 6.2.0  */
46 /*                                                                        */
47 /**************************************************************************/
48 
49 #ifndef TX_POSIX
50 #define TX_POSIX
51 
52 #include <stdarg.h>
53 #include <stdio.h>
54 #include <string.h>
55 
56 /************************************************************************/
57 /* Macros to convert between semaphore, queue, scheduler                */
58 /************************************************************************/
59 #define  MAKE_TX_SEM(sem)             ((TX_SEMAPHORE *)sem)
60 #define  MAKE_POSIX_QUEUE(queue)      ((POSIX_MSG_QUEUE *)queue)
61 #define  MAKE_POSIX_SEM(sem)          ((sem_t *)sem)
62 
63 /************************************************************************/
64 /* Define max values for message queue services                         */
65 /************************************************************************/
66 #define  MQ_MAXMSG                      125             /* MQ_MAXMSG 1024 (POSIX value).   */
67 #define  MQ_MSGSIZE                     500             /* MQ_MSGSIZE 4096 (POSIX value)   */
68 #define  MQ_FLAGS                       0
69 #define  MQ_PRIO_MAX                    32              /* Maximum priority of message.    */
70 
71 #ifdef TX_64_BIT
72 #define TX_POSIX_MESSAGE_SIZE           5
73 #define TX_POSIX_QUEUE_PRIORITY_OFFSET  3
74 #else
75 #define TX_POSIX_MESSAGE_SIZE           4
76 #define TX_POSIX_QUEUE_PRIORITY_OFFSET  2
77 #endif
78 /************************************************************************/
79 /*                          Global Variables                            */
80 /************************************************************************/
81 
82 /* to errno.h
83 #ifndef TX_POSIX_SOURCE
84 #define errno posix_errno
85 #endif
86 */
87 
88 /* Define the system configuration constants for the Evacuation Kit for
89    POSIX Users.This is where the number of system objects
90    (pthreads, message queues, semaphores etc.)are defined.              */
91 
92 /************************************************************************/
93 /*               SYSTEM CONFIGURATION PARAMETERS                        */
94 /************************************************************************/
95 
96 /* Define the maximum number of simultaneous POSIX semaphores
97     supported.  */
98 #define  SEM_NSEMS_MAX                  16
99 
100 /* Define the maximum length of name of semaphore .  */
101 #define  SEM_NAME_MAX                   10
102 
103 /* Max value of semaphore while initialization.  */
104 #define  SEM_VALUE_MAX                  100
105 
106 /* Define the maximum number of simultaneous POSIX message queues supported.  */
107 
108 #define  POSIX_MAX_QUEUES               16
109 
110 /* Define the maximum number of simultaneous POSIX pthreads supported.  */
111 #define  PTHREAD_THREADS_MAX            16
112 
113 /* Define the maximum number of simultaneous POSIX mutexes supported.  */
114 
115 #define  POSIX_MAX_MUTEX                16
116 
117 /* Define the maximum length of name of message queue.  */
118 #define  PATH_MAX                       10
119 
120 
121 /* Define size of the posix heap memory segment.                              */
122 /* NOTE:  This region should be large enough to supply the memory       */
123 /*        for all pthread stacks, pthread control blocks in the system  */
124 
125 #define  TX_DEFAULT_THREAD_STACK_SIZE   2048
126 #define  TX_REGION0_CONSTANT            14
127 #define  TX_REGION0_SIZE                ( (TX_DEFAULT_THREAD_STACK_SIZE+16) * TX_REGION0_CONSTANT)
128 
129 #define  POSIX_HEAP_SIZE_IN_BYTES       (TX_REGION0_SIZE * 4)
130 
131 
132 
133 
134 /* Define number of CPU ticks per second */
135 #define  CPU_TICKS_PER_SECOND           100  /* assuming 10 mSec tick */
136 #define  NANOSECONDS_IN_CPU_TICK        10000000  /* assuming 10 mSec tick */
137 
138 /* Define queue control specific data definitions.  */
139 
140 #define  TX_SEMAPHORE_ID                0x53454D41UL
141 #define  TX_QUEUE_ID                    0x51554555UL
142 #define  PX_QUEUE_ID                    0x51554555UL
143 #define  TX_MUTEX_ID                    0x4D555445UL
144 
145 /************************************************************************/
146 /*             Misc. POSIX-related definitions .                        */
147 /************************************************************************/
148 #define  POSIX_STACK_PADDING            1024
149 #define  POSIX_SYSTEM_STACK_SIZE        1024
150 #define  POSIX_PTHREAD_STACK_SIZE       1024
151 
152 /************************************************************************/
153 /*               ARCHITECTURE DEFINITIONS                               */
154 /************************************************************************/
155 /* Define all supported architectures here.  */
156 
157 #define  POSIX_POWERPC                  1
158 #define  POSIX_68K                      2
159 #define  POSIX_ARM                      3
160 #define  POSIX_MIPS                     4
161 
162 /* Define POSIX_ARCH as one of the above list.  */
163 
164 #define  POSIX_ARCH                     POSIX_POWERPC
165 
166 /* Make sure POSIX_ARCH is defined.  */
167 
168 #ifndef  POSIX_ARCH
169 #error   Must define symbol POSIX_ARCH to *something*!
170 #endif
171 
172 /* Define the minimum stack size for each supported architecture here.  */
173 
174 #define  MIN_STACKSIZE_POWERPC          2048
175 
176 /************************************************************************/
177 /*               MISCELLANEOUS CONSTANTS                                */
178 /************************************************************************/
179 /* Requests/commands to SysMgr task.  */
180 
181 #define   SYSMGR_DELETE_TASK            0
182 
183 /* pthread name length */
184 #define   PTHREAD_NAME_LEN              4
185 
186 #define   PTHREAD_CREATE_DETACHED       1
187 #define   PTHREAD_CREATE_JOINABLE       0
188 
189 /* scheduler related constants */
190 
191 #define   SCHED_PRIO_MAX                31
192 #define   SCHED_PRIO_MIN                1
193 
194 /* time slice value in ticks for round robin scheduler */
195 #define   SCHED_RR_TIME_SLICE           20
196 
197 #define   PTHREAD_MUTEX_NORMAL          1
198 #define   PTHREAD_MUTEX_RECURSIVE       2
199 #define   PTHREAD_MUTEX_ERRORCHECK      3
200 #define   PTHREAD_MUTEX_DEFAULT         PTHREAD_MUTEX_RECURSIVE
201 
202 #define   PTHREAD_PRIO_INHERIT          1
203 
204 #define   PTHREAD_PROCESS_PRIVATE       1
205 #define   PTHREAD_PROCESS_SHARED        2
206 
207 #define   PTHREAD_CANCEL_ENABLE         0           /* default */
208 
209 #define   PTHREAD_CANCEL_DISABLE        1
210 
211 #define   PTHREAD_CANCEL_DEFERRED       0          /* default */
212 
213 #define   PTHREAD_CANCEL_ASYNCHRONOUS   1
214 
215 #define   PTHREAD_INHERIT_SCHED         1
216 
217 #define   PTHREAD_EXPLICIT_SCHED        0
218 
219 #define   PTHREAD_ONCE_INIT             {0, 0, {0,NULL,0,0,NULL,0,NULL,NULL}}
220 
221 enum pth_once_state {
222   PTH_ONCE_INIT      = 0x0,
223   PTH_ONCE_DONE      = 0x1,
224   PTH_ONCE_STARTED   = 0x2,
225   PTH_ONCE_CANCELLED = 0x3
226 };
227 
228 /************************************************************************/
229 /*               ERROR CODES (those defined outside of POSIX)           */
230 /************************************************************************/
231 
232 #ifdef   ERROR
233 #undef   ERROR
234 #define  ERROR                  -1
235 #else
236 #define  ERROR                  -1
237 #endif
238 
239 #define NO_ERROR        0
240 
241 /* From semaphore.h, when px_sem_open fails: */
242 #define SEM_FAILED	((sem_t *) 0)
243 
244 #ifndef _WIN32
245 typedef  ULONG                  BOOL;
246 #endif
247 
248 
249 #ifndef  OK
250 #define  OK                     0
251 #endif
252 
253 #ifndef  FALSE
254 #define  FALSE                  0
255 #endif
256 
257 #ifndef  TRUE
258 #define  TRUE                   1
259 #endif
260 
261 #ifndef  NULL
262 #define  NULL                   0
263 #endif
264 
265 /* these constants control internal working of the systemmanager thread */
266 
267 #define   WORK_REQ_SIZE         (TX_2_ULONG * (sizeof(ALIGN_TYPE)/sizeof(ULONG)))
268 #define   WORK_QUEUE_DEPTH      10
269 
270 #define   SYSMGR_PRIORITY       0
271 #define   SYSMGR_THRESHOLD      0
272 
273 
274 /* STRUCTURES RELATED TO pthreads  */
275 
276 
277 
278 typedef struct pthread_attr_obj
279 {
280      ULONG                pthread_flags;
281      INT                  detach_state;
282      INT                  inherit_sched;
283      INT                  sched_policy;
284      struct sched_param   sched_attr;
285      VOID                *stack_address;
286      ULONG                stack_size;
287      INT                  inuse;
288 } pthread_attr_t;
289 
290 
291 typedef  INT    ssize_t ;     /* this should be pulled in from sys\types.h  */
292 typedef  ALIGN_TYPE  pthread_t;
293 typedef  ULONG  mode_t;
294 
295 
296 
297 /* Define POSIX Pthread control block tructure.  */
298 
299 typedef struct pthread_control_block
300 {
301     /* This pthread's ThreadX TCB.  */
302     TX_THREAD            thread_info;
303     /* This pthread's unique identifier */
304     pthread_t            pthreadID;
305     /* To check if posix Pthread is in use.  */
306     UINT                 in_use;
307     /* All pthread attributes contained in the a pthread_attr_t object */
308     ULONG                pthread_flags;
309     INT                  detach_state;
310     INT                  inherit_sched;
311     INT                  sched_policy;
312     struct sched_param   sched_attr;
313     VOID                *stack_address;
314     ULONG                stack_size;
315     INT                  cancel_state;
316     INT                  cancel_type;
317     /* Identifier of the target thread to which this pthread is joined */
318     pthread_t            joined_to_pthreadID;
319     /* Identifier of the caller thread which has joined to this thread*/
320     pthread_t            joined_by_pthreadID;
321     /* To check if posix pthread is joined to any other pthread */
322         UINT             is_joined_to;
323     /* To check if posix Pthread is joined by any other pthread */
324         UINT             is_joined_by;
325     /* To check if posix Pthread is in detached state or not */
326         UINT             is_detached;
327     /* Value returned by the terminating thread which is joined to this thread */
328     VOID                 *value_ptr;
329     /* Define the original pthread priority.  */
330     ULONG                orig_priority;
331     /* Define the current pthread priority.  */
332     ULONG                current_priority;
333     /* Define the pthread's pre-emption threshold.  */
334     ULONG                threshold;
335     /* Define the pthread's timeslice.  */
336     ULONG                time_slice;
337     /* specify pthread start routine */
338     VOID                 *(*start_routine)(VOID *);
339     /* specify argument for start up routine */
340     ULONG                *entry_parameter;
341     /* to hold error code for this pthread */
342     ULONG                perrno;
343     /* to hold pthread cancel request */
344     UINT                 cancel_request;
345 
346     /* Signal information follows.  */
347     signal_info          signals;
348 
349 }POSIX_TCB;
350 
351 typedef struct pthread_mutex_attr_obj
352 {
353      INT                 type;
354      INT                 protocol;
355      INT                 pshared;
356      INT                 in_use;
357 
358 } pthread_mutexattr_t;
359 
360 /* Define POSIX mutex structure.  */
361 
362 typedef struct pthread_mutex_control_block
363 {
364     /* This mutex's ThreadX Control block  */
365     TX_MUTEX      mutex_info;
366     /* This mutex's attributes */
367     INT           type;
368     /* Is this Mutex object is in use?  */
369     INT           in_use;
370 
371 } pthread_mutex_t;
372 
373 
374 /*     STRUCTURES RELATED TO POSIX MESSAGE QUEUE   */
375 
376 
377 struct mq_attr
378 {
379     /* No. of maximum messages.  */
380     ULONG         mq_maxmsg;
381     /* Size of the message.  */
382     ULONG         mq_msgsize;
383     /* Flags are ignored as these are passed separately in open().  */
384     ULONG         mq_flags;
385 };
386 
387 /* Define POSIX message queue structure.  */
388 typedef struct msg_que
389 {
390     /* Define ThreadX queue.  */
391     TX_QUEUE                      queue;
392     /* To check if posix queue is in use.  */
393     UINT                          in_use;
394     /* To check if queue is unlinked.  */
395     UINT                          unlink_flag;
396     /* Name of queue.  */
397     CHAR                        * name;
398     /* Attribute of queue.  */
399     struct mq_attr                q_attr;
400     /* To check no. of times queue is opened.  */
401     UINT                          open_count;
402     /* Address for variable length message.  */
403     VOID                        * storage;
404     /* Byte pool for variable length message.  */
405     TX_BYTE_POOL                  vq_message_area;
406     /* POSIX queue ID.  */
407     ULONG                         px_queue_id;
408 
409 }POSIX_MSG_QUEUE;
410 
411 /* Define Queue Descriptor.  */
412 typedef struct mq_des
413 {
414     /* Queue FLAGS.  */
415     ULONG                         f_flag;
416     /* message Queue structure.  */
417     POSIX_MSG_QUEUE             * f_data;
418 
419 } *mqd_t;
420 
421 
422 /* STRUCTURES RELATED TO POSIX SEMAPHORES  */
423 
424 typedef struct POSIX_SEMAPHORE_STRUCT
425 {
426     /* ThreadX semaphore.  */
427     TX_SEMAPHORE                  sem;
428     /* To check if semaphore is in use.  */
429     UINT                          in_use;
430     /* semaphore identifier  */
431     ULONG                         psemId;
432     /* number of attachments  */
433     ULONG                         refCnt;        /* previously it was int  */
434      /* name of semaphore  */
435     char                        * sem_name;
436     /* Open Count.  */
437     ULONG                         count;
438     /* For unlink flag.  */
439     ULONG                         unlink_flag;
440 
441 } sem_t;
442 
443 typedef sem_t             *SEM_ID;
444 
445 typedef struct pthread_cond_obj
446 {
447     /* This pthread condition variable's internal counting Semaphore  */
448     TX_SEMAPHORE        cond_semaphore;
449 
450     INT                 type;
451     INT                 in_use;
452 
453 } pthread_cond_t;
454 
455 typedef struct pthread_condattr_obj
456 {
457 /*     INT                 type; */
458      INT                 in_use;
459 
460 } pthread_condattr_t;
461 
462 
463 
464 typedef struct  pthread_once_obj
465 {
466   UINT          state;
467   ULONG          flags;
468   TX_EVENT_FLAGS_GROUP   event;
469 }pthread_once_t;
470 
471 
472 /* Define extern for errno variable.  */
473 
474 extern unsigned int   posix_errno;
475 
476 
477 
478 /* Define POSIX initialize prototype.  */
479 
480 VOID                 *posix_initialize(VOID * posix_memory);
481 
482 /* Define POSIX API function prototypes.  */
483 
484 INT                   mq_send(mqd_t mqdes, const char * msg_ptr,
485                                 size_t msg_len,ULONG msg_prio );
486 ssize_t               mq_receive(mqd_t mqdes, VOID *pMsg, size_t msgLen,
487                                    ULONG *pMsgPrio );
488 INT                   mq_unlink(const char * mqName);
489 INT                   mq_close(mqd_t mqdes);
490 mqd_t                 mq_open(const CHAR * mqName, ULONG oflags,...);
491 INT                   sem_close(sem_t  * sem);
492 INT                   sem_getvalue(sem_t * sem,ULONG * sval);
493 sem_t                *sem_open(const char * name, ULONG oflag, ...);
494 INT                   sem_post(sem_t * sem);
495 INT                   sem_trywait(sem_t * sem);
496 INT                   sem_unlink(const char * name);
497 INT                   sem_wait( sem_t * sem );
498 INT                   sem_init(sem_t *sem , INT pshared, UINT value);
499 INT                   sem_destroy(sem_t *sem);
500 
501 INT                   pthread_create (pthread_t *thread,  pthread_attr_t *attr,
502                                       VOID *(*start_routine)(VOID*),VOID *arg);
503 INT                   pthread_detach(pthread_t thread);
504 INT                   pthread_join(pthread_t thread, VOID **value_ptr);
505 INT                   pthread_equal(pthread_t thread1, pthread_t thread2);
506 VOID                  pthread_exit(VOID *value_ptr);
507 pthread_t             pthread_self(VOID);
508 INT                   pthread_attr_destroy(pthread_attr_t *attr);
509 INT                   pthread_attr_getdetachstate( pthread_attr_t *attr,INT *detachstate);
510 INT                   pthread_attr_setdetachstate(pthread_attr_t *attr,INT detachstate);
511 INT                   pthread_attr_getinheritsched(pthread_attr_t *attr, INT *inheritsched);
512 INT                   pthread_attr_setinheritsched(pthread_attr_t *attr, INT inheritsched);
513 INT                   pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param);
514 INT                   pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param *param);
515 INT                   pthread_attr_getschedpolicy(pthread_attr_t *attr, INT *policy);
516 INT                   pthread_attr_setschedpolicy(pthread_attr_t *attr, INT policy);
517 INT                   pthread_attr_init(pthread_attr_t *attr);
518 INT                   pthread_attr_getstackaddr( pthread_attr_t *attr,VOID **stackaddr);
519 INT                   pthread_attr_setstackaddr(pthread_attr_t *attr,VOID *stackaddr);
520 INT                   pthread_attr_getstacksize( pthread_attr_t *attr, size_t *stacksize);
521 INT                   pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
522 INT                   pthread_attr_getstack( pthread_attr_t *attr,VOID **stackaddr,
523                                            size_t *stacksize);
524 INT                   pthread_attr_setstack( pthread_attr_t *attr,VOID *stackaddr,
525                                             size_t stacksize);
526 INT                   pthread_mutexattr_gettype(pthread_mutexattr_t *attr, INT *type);
527 INT                   pthread_mutexattr_settype(pthread_mutexattr_t *attr, INT type);
528 INT                   pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
529 INT                   pthread_mutexattr_init(pthread_mutexattr_t *attr);
530 INT                   pthread_mutex_destroy(pthread_mutex_t *mutex);
531 INT                   pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
532 INT                   pthread_mutex_lock(pthread_mutex_t *mutex );
533 INT                   pthread_mutex_unlock(pthread_mutex_t *mutex );
534 INT                   pthread_mutex_trylock(pthread_mutex_t *mutex);
535 INT                   pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr, INT *protocol);
536 INT                   pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, INT protocol);
537 INT                   pthread_mutexattr_getpshared (pthread_mutexattr_t *attr, INT *pshared);
538 INT                   pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, INT pshared);
539 INT                   pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout);
540 INT                   pthread_setcancelstate (INT state, INT *oldstate);
541 INT                   pthread_setcanceltype (INT type, INT *oldtype);
542 INT                   pthread_cancel(pthread_t thread);
543 VOID                  pthread_yield(VOID);
544 INT                   pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID));
545 VOID                  pthread_testcancel(VOID);
546 INT                   pthread_setschedparam(pthread_t thread, INT policy, const struct sched_param *param);
547 INT                   pthread_getschedparam(pthread_t thread, INT *policy, struct sched_param *param);
548 
549 INT                   pthread_cond_destroy(pthread_cond_t *cond);
550 INT                   pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);
551 INT                   pthread_cond_broadcast(pthread_cond_t *cond);
552 INT                   pthread_cond_signal(pthread_cond_t *cond);
553 INT                   pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,
554                                                  struct timespec *abstime);
555 INT                   pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
556 
557 
558 
559 
560 
561 
562 /* static mutex initializer */
563 
564 #define PTHREAD_MUTEX_INITIALIZER  {{TX_MUTEX_ID, "PMTX", 0, NULL, 0, 0, 0,  NULL, 0 , NULL, NULL}, PTHREAD_MUTEX_RECURSIVE , TX_TRUE}
565 
566 /* static conditional variable initializer */
567 #define PTHREAD_COND_INITIALIZER  {{TX_SEMAPHORE_ID, "CSEM", 0, NULL, 0, NULL, NULL}, TX_TRUE}
568 
569 
570 
571 
572 
573 
574 #endif      /* TX_POSIX  */
575