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