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