You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The POSIX compatibility layer cannot work on a 64-bit port. It compiles there and produces a library, but its message queues corrupt the pointer they carry, and the configuration that would fix that does not build. This came out of wiring the layer into CMake in #626.
Why it is broken as it stands
The layer passes a message by allocating a private buffer, copying the caller's data into it and putting the buffer's address into a ThreadX queue. ULONG is 32 bits on every ThreadX port, including the 64-bit ones, so on a 64-bit target that address does not fit in a message word.
tx_posix.h accounts for this with TX_64_BIT, which widens the message and splits the pointer across two words:
with matching code in px_mq_send.c:198 and px_mq_receive.c:209. Without TX_64_BIT the send truncates the pointer and the receive casts the truncated value back. The compiler says nothing worse than a warning, which is why the target builds cleanly on AArch64 and RV64:
px_mq_send.c:205:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
px_mq_receive.c:214:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
Why defining TX_64_BIT does not fix it
TX_64_BIT is never defined by any port; it is only ever tested. Defining it makes tx_api.h use the extension pointer macros, which need tx_thread_extension_ptr in the thread control block:
px_pth_create.c:235:5: error: 'TX_THREAD' has no member named 'tx_thread_extension_ptr'
px_pth_init.c:361:5: error: 'TX_THREAD' has no member named 'tx_thread_extension_ptr'
Outside ports_smp and ports/linux, no port declares it. None of risc-v64, cortex_a53, cortex_a55 or cortex_a34 does.
What I measured
I prototyped the whole thing on risc-v64 to find out how much is actually missing.
The port change is one line.risc-v64 has an empty slot already:
cortex_a53 and the other 64-bit Arm ports have a free slot too. This is the same declaration ports_smp/cortex_a72_smp already carries.
With that line and -DTX_64_BIT, the layer compiles clean. All 106 sources plus the #626 tests, riscv64-unknown-elf, -Werror, no warnings.
But it deadlocks at runtime. Built for risc-v64 and run under qemu-system-riscv64, the test produces no output at all. Attaching gdb shows the system parked in the idle loop with nothing runnable:
#0 _tx_thread_schedule_loop () at ports/risc-v64/gnu/src/tx_thread_schedule.S:77
#1 _tx_thread_system_suspend (thread_ptr=0x801012d0 <ptcb_pool>) at common/src/tx_thread_system_suspend.c:372
with these threads:
thread
state
meaning
System Timer Thread
3
suspended
test control thread
3
suspended
POSIX System Manager
5
waiting on its work queue (expected)
pthr
4
TX_SLEEP
The worker pthread is asleep although the test never sleeps, and nothing wakes it. The same BSP and QEMU invocation run the stock ThreadX RISC-V64 regression tests without trouble, so this is the layer rather than the port or the harness.
What is already correct
Worth recording, because it narrows the search. Every TX_64_BIT path I checked handles 64 bits properly:
px_mq_send.c:198 / px_mq_receive.c:209 — the message pointer split.
px_pth_init.c:720 / px_system_manager.c:87 — the work request pack and unpack.
WORK_REQ_SIZE in tx_posix.h:257 — already scales by sizeof(ALIGN_TYPE)/sizeof(ULONG).
So the 64-bit paths were written plausibly; they appear never to have been executed. The remaining defect is somewhere less obvious, and there is likely more than one.
Suggested work
Add tx_thread_extension_ptr to the 64-bit ports. Trivial, but the generated ports need regenerating rather than hand-editing.
The POSIX compatibility layer cannot work on a 64-bit port. It compiles there and produces a library, but its message queues corrupt the pointer they carry, and the configuration that would fix that does not build. This came out of wiring the layer into CMake in #626.
Why it is broken as it stands
The layer passes a message by allocating a private buffer, copying the caller's data into it and putting the buffer's address into a ThreadX queue.
ULONGis 32 bits on every ThreadX port, including the 64-bit ones, so on a 64-bit target that address does not fit in a message word.tx_posix.haccounts for this withTX_64_BIT, which widens the message and splits the pointer across two words:with matching code in
px_mq_send.c:198andpx_mq_receive.c:209. WithoutTX_64_BITthe send truncates the pointer and the receive casts the truncated value back. The compiler says nothing worse than a warning, which is why the target builds cleanly on AArch64 and RV64:Why defining TX_64_BIT does not fix it
TX_64_BITis never defined by any port; it is only ever tested. Defining it makestx_api.huse the extension pointer macros, which needtx_thread_extension_ptrin the thread control block:Outside
ports_smpandports/linux, no port declares it. None ofrisc-v64,cortex_a53,cortex_a55orcortex_a34does.What I measured
I prototyped the whole thing on
risc-v64to find out how much is actually missing.The port change is one line.
risc-v64has an empty slot already:cortex_a53and the other 64-bit Arm ports have a free slot too. This is the same declarationports_smp/cortex_a72_smpalready carries.With that line and
-DTX_64_BIT, the layer compiles clean. All 106 sources plus the #626 tests,riscv64-unknown-elf,-Werror, no warnings.But it deadlocks at runtime. Built for
risc-v64and run underqemu-system-riscv64, the test produces no output at all. Attaching gdb shows the system parked in the idle loop with nothing runnable:with these threads:
pthrThe worker pthread is asleep although the test never sleeps, and nothing wakes it. The same BSP and QEMU invocation run the stock ThreadX RISC-V64 regression tests without trouble, so this is the layer rather than the port or the harness.
What is already correct
Worth recording, because it narrows the search. Every
TX_64_BITpath I checked handles 64 bits properly:px_mq_send.c:198/px_mq_receive.c:209— the message pointer split.px_pth_init.c:720/px_system_manager.c:87— the work request pack and unpack.WORK_REQ_SIZEintx_posix.h:257— already scales bysizeof(ALIGN_TYPE)/sizeof(ULONG).So the 64-bit paths were written plausibly; they appear never to have been executed. The remaining defect is somewhere less obvious, and there is likely more than one.
Suggested work
tx_thread_extension_ptrto the 64-bit ports. Trivial, but the generated ports need regenerating rather than hand-editing.test/posix/cmake/CMakeLists.txtcurrently stops with an explanation forrisc-v64, and that becomesadd_compile_options(-DTX_64_BIT).TX_64_BITfails instead of producing a library whose queues do not work.Step 1 is an hour. Step 2 is the real cost: it is bring-up of code that has never run, so it is hard to bound. #626 gives somewhere to run it.