Closed salkinium closed 5 months ago
It's still missing unit tests for latch, barrier and condition_variable and a bunch of documentation, however, it would be amazing if this could get reviewed with a special focus on C++ "conformity". This implementation should be interrupt-safe (when it makes sense for the functions), so that we can use then in the HAL as signalling primitives for operation completions in the future.
I also noticed that avrlibstd++ does not have <atomic>
, I assume it was really annoying to port, @chris-durand? If it's an issue with the builtin gcc atomics not being implemented for avr-gcc, we can reuse the Cortex-M0 ones now.
I also noticed that avrlibstd++ does not have
<atomic>
, I assume it was really annoying to port, @chris-durand? If it's an issue with the builtin gcc atomics not being implemented for avr-gcc, we can reuse the Cortex-M0 ones now.
I haven't tried to be honest but I expect that the same solution as for Cortex-M0 will work. The header is mostly implemented using compiler builtins. I'd expect it to fall back to calling a library function in case the operation is not atomic on AVR. If you are lucky just dropping in the headers and compiling atomics_c11_cortex.cpp.in
for AVR could be sufficient.
C++20 atomic wait which requires OS support shouldn't be an issue because it is only enabled when _GLIBCXX_HAS_GTHREADS
is set.
I'll take a look at the PR over the weekend.
If you are lucky just dropping in the headers and compiling
atomics_c11_cortex.cpp.in
for AVR could be sufficient.
Yup that just works, thanks!
@chris-durand, I added ARMv8-M stack protection, could you check if the example/generic/fiber still works? I don't have a Cortex-M33 in my collection.
@chris-durand, I added ARMv8-M stack protection, could you check if the example/generic/fiber still works? I don't have a Cortex-M33 in my collection.
When running this on an STM32L5 I get a hardfault. The stack overflow bit (STKOF, bit 4) in UFSR is set. The fault happens inside modm_context_jump
, triggered from the call to yield()
inside the lambda of fiber_y1
.
Let me know if there is something specific I can check.
Hm, so setting MSPLIM is no problem, setting PSPLIM once on context_start is no problem either, but then on the first context switch it fails? ugh.
Could you try to change the assembly in context_jump?
%% elif with_psplim
- "ldm r1, {r1-r2} \n\t"
- "mov sp, r1 \n\t" // Set PSP to ctx->sp
- "msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
+ "ldm r1, {r2-r3} \n\t"
+ "mov sp, r2 \n\t" // Set PSP to ctx->sp
+ "msr psplim, r3 \n\t" // Set PSPLIM to ctx->bottom
%% else
%% elif with_psplim
- "ldm r1, {r1-r2} \n\t"
- "mov sp, r1 \n\t" // Set PSP to ctx->sp
- "msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
+ "ldr sp, [r1] \n\t" // Set PSP to ctx->sp
+ "ldr r2, [r1, #4] \n\t"
+ "msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
%% else
%% elif with_psplim
- "ldm r1, {r1-r2} \n\t"
- "mov sp, r1 \n\t" // Set PSP to ctx->sp
- "msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
+ "ldm r1, {r2-r3} \n\t"
+ "msr psplim, r3 \n\t" // Set PSPLIM to ctx->bottom
+ "mov sp, r2 \n\t" // Set PSP to ctx->sp
%% else
%% elif with_psplim
- "ldm r1, {r1-r2} \n\t"
- "mov sp, r1 \n\t" // Set PSP to ctx->sp
- "msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
+ "ldr r2, [r1, #4] \n\t"
+ "msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
+ "ldr sp, [r1] \n\t" // Set PSP to ctx->sp
%% else
No success with any of the options. I've also tried replacing the code in both context_start and context_jump.
Ok, then I'll descope it for now and will order a bunch of new development boards and debug it some more. Thanks for your help!
Fibers need a standard set of efficient constructs. I modelled these classes after the C++ thread concurrency interfaces. Not sure if useful, but also probably not really much room for improvement anyways.
modm::fiber::sleep
->modm::this_fiber::sleep_for
modm::this_fiber::sleep_until
modm::this_fiber::get_id
modm::fiber::Task
tostd::jthread
interface, incl. stop_token.