diff options
Diffstat (limited to 'utility/rtos_compatibility_layers/posix')
9 files changed, 201 insertions, 12 deletions
diff --git a/utility/rtos_compatibility_layers/posix/CMakeLists.txt b/utility/rtos_compatibility_layers/posix/CMakeLists.txt new file mode 100644 index 00000000..8cf3ab9a --- /dev/null +++ b/utility/rtos_compatibility_layers/posix/CMakeLists.txt @@ -0,0 +1,130 @@ +# POSIX compatibility layer for ThreadX. +# +# This target is EXCLUDE_FROM_ALL: it is not part of the default build and is +# only produced when something asks for it, either by name or by linking it. +# +# The include directory is deliberately PUBLIC. The layer ships replacements for +# errno.h, fcntl.h, pthread.h, sched.h, signal.h and time.h, and application code +# has to see those rather than a toolchain's own copies. That is also why the +# layer cannot be used on the hosted simulation ports, where the C library +# already supplies them; the top-level CMakeLists.txt skips it there. + +add_library(posix-threadx EXCLUDE_FROM_ALL) + +target_include_directories(posix-threadx + SYSTEM + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +target_sources(posix-threadx + PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/px_abs_time_to_rel_ticks.c + ${CMAKE_CURRENT_LIST_DIR}/px_clock_getres.c + ${CMAKE_CURRENT_LIST_DIR}/px_clock_gettime.c + ${CMAKE_CURRENT_LIST_DIR}/px_clock_settime.c + ${CMAKE_CURRENT_LIST_DIR}/px_cond_broadcast.c + ${CMAKE_CURRENT_LIST_DIR}/px_cond_destroy.c + ${CMAKE_CURRENT_LIST_DIR}/px_cond_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_cond_signal.c + ${CMAKE_CURRENT_LIST_DIR}/px_cond_timedwait.c + ${CMAKE_CURRENT_LIST_DIR}/px_cond_wait.c + ${CMAKE_CURRENT_LIST_DIR}/px_error.c + ${CMAKE_CURRENT_LIST_DIR}/px_in_thread_context.c + ${CMAKE_CURRENT_LIST_DIR}/px_internal_signal_dispatch.c + ${CMAKE_CURRENT_LIST_DIR}/px_memory_allocate.c + ${CMAKE_CURRENT_LIST_DIR}/px_memory_release.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_arrange_msg.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_attr_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_close.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_create.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_find_queue.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_get_new_queue.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_get_queue_desc.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_open.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_priority_search.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_putback_queue.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_queue_delete.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_queue_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_receive.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_reset_queue.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_send.c + ${CMAKE_CURRENT_LIST_DIR}/px_mq_unlink.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_destroy.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_getprotocol.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_getpshared.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_gettype.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_initi.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_setprotocol.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_setpshared.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_attr_settype.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_destroy.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_lock.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_set_default_mutexattr.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_timedlock.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_trylock.c + ${CMAKE_CURRENT_LIST_DIR}/px_mx_unlock.c + ${CMAKE_CURRENT_LIST_DIR}/px_nanosleep.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_destroy.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getdetachstate.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getinheritsched.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getschedparam.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getschedpolicy.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getstack.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getstackaddr.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_getstacksize.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setdetachstate.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setinheritsched.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setschedparam.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setschedpolicyl.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setstack.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setstackaddr.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_attr_setstacksize.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_cancel.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_create.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_detach.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_equal.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_exit.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_getcanceltype.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_getschedparam.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_join.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_kill.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_once.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_self.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_set_default_pthread_attr.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_setcancelstate.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_setcanceltype.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_setschedparam.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_sigmask.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_testcancel.c + ${CMAKE_CURRENT_LIST_DIR}/px_pth_yield.c + ${CMAKE_CURRENT_LIST_DIR}/px_px_initialize.c + ${CMAKE_CURRENT_LIST_DIR}/px_sched_get_prio.c + ${CMAKE_CURRENT_LIST_DIR}/px_sched_yield.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_close.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_destroy.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_find_sem.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_get_new_sem.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_getvalue.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_init.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_open.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_post.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_reset.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_set_sem_name.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_trywait.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_unlink.c + ${CMAKE_CURRENT_LIST_DIR}/px_sem_wait.c + ${CMAKE_CURRENT_LIST_DIR}/px_sig_addset.c + ${CMAKE_CURRENT_LIST_DIR}/px_sig_delset.c + ${CMAKE_CURRENT_LIST_DIR}/px_sig_emptyset.c + ${CMAKE_CURRENT_LIST_DIR}/px_sig_fillset.c + ${CMAKE_CURRENT_LIST_DIR}/px_sig_signal.c + ${CMAKE_CURRENT_LIST_DIR}/px_sig_wait.c + ${CMAKE_CURRENT_LIST_DIR}/px_sleep.c + ${CMAKE_CURRENT_LIST_DIR}/px_system_manager.c +) + +target_link_libraries(posix-threadx PUBLIC threadx) diff --git a/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c b/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c index f9c8f151..fe54532c 100644 --- a/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c +++ b/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -91,7 +92,7 @@ UINT old_threshold,dummy; /* Get the condition variable's internal semaphore. */ - /* Simply convert the condition variable control block into a semaphore a cast */ + /* Simply convert the condition variable control block into a semaphore using casting. */ semaphore_ptr = (&( cond->cond_semaphore )); sem_count = semaphore_ptr->tx_semaphore_suspended_count; diff --git a/utility/rtos_compatibility_layers/posix/px_cond_destroy.c b/utility/rtos_compatibility_layers/posix/px_cond_destroy.c index efa99be1..5f9d8f8a 100644 --- a/utility/rtos_compatibility_layers/posix/px_cond_destroy.c +++ b/utility/rtos_compatibility_layers/posix/px_cond_destroy.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -80,7 +81,7 @@ UINT status; { cond->in_use = TX_FALSE; /* Get the condition variable's internal semaphore. */ - /* Simply convert the Condition variable control block into a semaphore a cast */ + /* Simply convert the condition variable control block into a semaphore using casting. */ semaphore_ptr = (&( cond->cond_semaphore )); status = tx_semaphore_delete(semaphore_ptr); if (status != TX_SUCCESS) diff --git a/utility/rtos_compatibility_layers/posix/px_cond_init.c b/utility/rtos_compatibility_layers/posix/px_cond_init.c index b376132d..27bfd41d 100644 --- a/utility/rtos_compatibility_layers/posix/px_cond_init.c +++ b/utility/rtos_compatibility_layers/posix/px_cond_init.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -72,7 +73,7 @@ UINT status; cond->in_use = TX_TRUE; /* Get the condition variable's internal semaphore. */ - /* Simply convert the COndition variable control block into a semaphore a cast */ + /* Simply convert the condition variable control block into a semaphore using casting. */ semaphore_ptr = (&( cond->cond_semaphore )); /* Now create the internal semaphore for this cond variable */ status = tx_semaphore_create(semaphore_ptr,"csem",0); diff --git a/utility/rtos_compatibility_layers/posix/px_cond_signal.c b/utility/rtos_compatibility_layers/posix/px_cond_signal.c index b1f4f285..611202ac 100644 --- a/utility/rtos_compatibility_layers/posix/px_cond_signal.c +++ b/utility/rtos_compatibility_layers/posix/px_cond_signal.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -84,7 +85,7 @@ TX_SEMAPHORE *semaphore_ptr; UINT status; /* Get the condition variable's internal semaphore. */ - /* Simply convert the COndition variable control block into a semaphore a cast */ + /* Simply convert the condition variable control block into a semaphore using casting. */ semaphore_ptr = (&( cond->cond_semaphore )); if ( semaphore_ptr->tx_semaphore_suspended_count) { diff --git a/utility/rtos_compatibility_layers/posix/px_mq_send.c b/utility/rtos_compatibility_layers/posix/px_mq_send.c index 464af01f..f641419a 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_send.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_send.c @@ -60,6 +60,7 @@ /* */ /* tx_thread_identify returns currently running thread */ /* tx_byte_allocate allocate memory */ +/* tx_byte_release release memory */ /* tx_queue_send ThreadX queue send */ /* posix_priority_search search message for same priority */ /* */ @@ -166,7 +167,16 @@ ULONG msg[TX_POSIX_MESSAGE_SIZE]; if (temp1 != TX_SUCCESS) { - posix_internal_error(9999); + posix_internal_error(9999); + + /* posix_internal_error() does not return today, but do not depend on + that: bp is indeterminate here, so falling through would copy + msg_len bytes through an unset pointer. */ + posix_errno = ENOMEM; + posix_set_pthread_errno(ENOMEM); + + /* Return ERROR. */ + return(ERROR); } /* Got the memory , Setup source and destination pointers Cast them in UCHAR as message length is in bytes. */ @@ -201,9 +211,14 @@ ULONG msg[TX_POSIX_MESSAGE_SIZE]; temp1 = tx_queue_send(Queue, msg, TX_WAIT_FOREVER); if ( temp1 != TX_SUCCESS) { + /* The message was never handed over to the queue, so this function + still owns the private buffer. Release it before returning, + otherwise it is leaked from the queue's byte pool. */ + tx_byte_release(bp); + /* POSIX doesn't have error for this, hence give default. */ posix_errno = EINTR ; - posix_set_pthread_errno(EINTR); + posix_set_pthread_errno(EINTR); /* Return ERROR. */ return(ERROR); diff --git a/utility/rtos_compatibility_layers/posix/px_pth_init.c b/utility/rtos_compatibility_layers/posix/px_pth_init.c index 5d2f36ad..ff0a01a9 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_init.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_init.c @@ -538,12 +538,30 @@ POSIX_TCB *p_tcb; if (!thread_ptr) { /* Not called from a thread - error! */ - posix_internal_error(222); + posix_internal_error(222); + + /* posix_internal_error() does not return today, but do not depend on + that: posix_thread2tcb() hands back NULL for this input and the read + below would dereference it. A pthread ID is the address of the TCB, + so zero is never a valid one. */ + return((pthread_t) 0); } /* Get the TCB for this pthread */ p_tcb = posix_thread2tcb(thread_ptr); + + /* A running ThreadX thread that was not created through pthread_create() + has no TCB in the pool, and posix_thread2tcb() returns NULL for it. It + has no pthread ID either, so report zero rather than reading through the + null pointer. Zero can never collide with a real ID, because + px_pth_create.c uses the address of the TCB as the ID. */ + if (!p_tcb) + { + + return((pthread_t) 0); + } + thread_ID = p_tcb->pthreadID; /* All done. */ diff --git a/utility/rtos_compatibility_layers/posix/px_pth_self.c b/utility/rtos_compatibility_layers/posix/px_pth_self.c index fd876459..2272fa31 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_self.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_self.c @@ -74,12 +74,21 @@ pthread_t thread_ID; thread_ID = posix_thread2tid(thread_ptr); - /* Determine if this thread is actually the signal thread helper. */ - if (((POSIX_TCB *) thread_ptr) -> signals.signal_handler) + /* Only a pthread has the signal fields read below: they belong to the + POSIX_TCB that surrounds the thread, and reading them through anything + else runs off the end of a plain TX_THREAD. A zero ID means the caller + is not a pthread, either because it is a ThreadX thread created directly + or because there is no current thread at all, so leave it alone. */ + if (thread_ID != (pthread_t) 0) { - /* Yes, override the thread_ID with the non-signal thread ID. */ - thread_ID = (pthread_t) ((POSIX_TCB *) thread_ptr) -> signals.base_thread_ptr; + /* Determine if this thread is actually the signal thread helper. */ + if (((POSIX_TCB *) thread_ptr) -> signals.signal_handler) + { + + /* Yes, override the thread_ID with the non-signal thread ID. */ + thread_ID = (pthread_t) ((POSIX_TCB *) thread_ptr) -> signals.base_thread_ptr; + } } diff --git a/utility/rtos_compatibility_layers/posix/tx_posix.h b/utility/rtos_compatibility_layers/posix/tx_posix.h index ce533dd8..3f235cb9 100644 --- a/utility/rtos_compatibility_layers/posix/tx_posix.h +++ b/utility/rtos_compatibility_layers/posix/tx_posix.h @@ -278,9 +278,22 @@ typedef struct pthread_attr_obj } pthread_attr_t; -typedef INT ssize_t ; /* this should be pulled in from sys\types.h */ +/* ssize_t and mode_t belong to <sys/types.h>. A C library that has already + declared them wins: it knows the target's real widths, and on an LP64 target + ssize_t is 64 bits while INT is not. newlib guards each type with its own + _*_DECLARED macro, so honour those and only define what is missing. A port + whose library uses different guards can predefine them to the same effect. */ +#ifndef _SSIZE_T_DECLARED +typedef INT ssize_t ; +#define _SSIZE_T_DECLARED +#endif + typedef ALIGN_TYPE pthread_t; + +#ifndef _MODE_T_DECLARED typedef ULONG mode_t; +#define _MODE_T_DECLARED +#endif |
