Samraksh / eMote

eMote OS -- Multiple Ports (using .NET MF v4.3)
0 stars 0 forks source link

Can't deploy C# to TinyCLR debug builds #249

Closed Nathan-Stohs closed 9 years ago

Nathan-Stohs commented 9 years ago

Can't deploy C# to TinyCLR debug builds. Release builds work.

Broken in Master, offending commit seems to be 9936149e94c88ecb9f90d139dfbb711414fe267b.

MichaelAtSamraksh commented 9 years ago

I am paranoid that this has to do with GlobalLocks. I fixed the semantics for GlobalLocks one week ago. Same behavior: calling GlobalLock(var); creates a smart pointer named var and turns the interrupts off. New behavior: GlobalLocks nest. So as more code calls GlobalLock, the locks are nested on the stack, so interrupts are not re-enabled until the last global lock is released. Previously, while debugging some other issue, Nived fundamentally broke GlobalLocks to enable interrupts whenever any lock was destroyed (instead of the originating lock). I'm still working up profiling code to demonstrate the more subtle issues with that behavior (That's why I asked Nathan off-line about exposing the STM32F103's ARM ETM pins for instruction trace). I hope to document GlobalLocks on the wiki when the profiling results are complete. Bottom line: make sure you know where and when your GlobalLocks are releasing their locks. In the past, it was common for Nived to solve a problem by just adding a global lock at the top of some section of code, which led to the system slowing down to the point where Nived gave up and ripped out the GlobalLock nesting behavior. To recap, it's not wrong to use Global Locks, but it is bad to use Global Locks without thinking about what they're doing or where exactly they are needed. I have not reviewed Chris's commit that Nathan linked to, but I'm posting this because i'm paranoid that global locks are what caused the commit to create that behavior, and I want everyone to be aware of the new fixed behavior. If you no longer need a lock, you can call var.Release();. File is at https://github.com/Samraksh/MF/blob/master/MicroFrameworkPK_v4_3/DeviceCode/Targets/Native/STM32F10x/DeviceCode/cores/arm/Common/GlobalLock/gcc-thumb2/SmartPtr_thumb2.cpp

Nathan-Stohs commented 9 years ago

After talking to Chris on a related issue, I spent 20 minutes on this. I see two problems:

If I ruthlessly remove locks from the MF PAL that are in the COM receive chain, I can eek out enough performance for TinyBooter/TinyCLR to respond to ping in debug mode at 48 MHz (high-power), but not 8 MHz (low-power).

If I then also replace the VT, I can further increase responsiveness enough for TinyBooter to be happy even down to 8 MHz in debug mode (something previously unheard of).

While it isn't absolutely critical that debug builds be fully capable, I would expect that this would have implications for user performance in the release builds as well.

What we are up against are the performance deadlines of the default baud rate (115200), our lack of hardware flow control, and the fragility of the underlying MF debug protocol. In the above mentioned cases, we just can't service the buffer fast enough and get RX overflows and the whole system falls apart.

Alternatively to directly improving performance, Mike informs me that we can recompile and distribute our own DLLs to slow the baud rate down to say 57600 or maybe even 19200. This is less desirable for a number of reasons, but maybe better than nothing.

MichaelAtSamraksh commented 9 years ago

This is larger than GlobalLocks. It also involves the NVIC priority system and pre-emption. Nived used full 16-level priority assignments, so higher priority IRQs could always interrupt lower priority IRQs. The interrupt controller's number of priority levels were modified (from the UART driver, tsk, tsk :0) when Nathan added the much needed UART TURBO mode, and it is not clear to me that anybody has a handle on balancing pre-emption with performance.

I mentioned some of the lock usage may not be needed (this was the discussion about the radio).

ChrisAtSamraksh commented 9 years ago

This build stops a lot of needless banging on the virtual timer code and allows deployment in debug builds. 2e22b811a85ff3f68eeac437d6e948562dad3c1a Deployment does not seem as reliable as it has in the past so if we can improve code efficiency it can help.