As CPUs get more powerful in general, so too do the little development boards. I can spend $10 on a board with multiple cores and megabytes of ram to drive my blinky lights and do wifi - that's enough power to run a full unix.
I have STM32 and Beaglebone too but have not used them yet.
Or google "esp-32" to find store selling a very popular one.
Or check out what's available on sparkfun or adafruit.
Within the past few weeks, they introduced a wireless version - the Pi Pico W. It's about $6 from authorized resellers, though stock is hard to find at the moment.
https://www.raspberrypi.com/documentation/microcontrollers/
https://www.raspberrypi.com/news/raspberry-pi-pico-w-your-6-...
Even? That's nearly the lowest bar regarding multitasking, compared to other OSes of the time.
Arduino's framework divides main() into two functions: Setup() and loop(), but they're essentially the same as whatever comes before the while loop, and the while loop itself, in a standard embedded c main function.
Then you just have interrupts setting states, and the loop responds to the change in state.
This adds enough of a delay that I moved some code to the other core on the Pico to get precise timing.
I never ran into an issue of quasi-hidden behaviors like that, because I never pushed the thing that hard. It feels a little bit like the Arduino toolset (that is pre IDE 2.0) was designed to discourage people from pushing things that hard.
Since switching to VSCode and PlatformIO, I read the source more. (Arduino 1.x discouraged this due to not having easy ways to navigate between callers and callees.)
[1] https://www.arduino.cc/reference/en/libraries/scheduler/yiel... [2] https://github.com/PaulStoffregen/cores/blob/master/teensy4/...
But the most usual thing was knowing the precise timings that takes instructions and the peripherals to allow do multiple things at same time.