This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Knowing current context




Nick Garnett wrote:

David Brennan <eCos@brennanhome.com> writes:



For our application, it is desirable to know if a section of code is
running in interrupt context. (Specifically we have a custom assert
function, and our arrays are protected, so if the interrupt routine
goes out of bounds on the array, the assert will fire. We are in the
process of writing a custom "print" function that can be used in
interrupt context, but we only want it to work in interrupt context,
otherwise we will use our normal messaging system.) This code performs
that function. (Although it requires platform specific implementation
in vectors.S, which I provided for i386.) I went ahead and put DSR
tracking in also, although it is not as necessary for our application.




I don't really like this. It is even more overhead in the interrupt
path that we really don't want. Those increments are likely to cause
cache misses and make interrupt handling even slower.



Since this code does nearly the same thing, I assumed the incl was not too expensive. I don't know how caching is actually implemented, but is it possible to put my _cyg_kernel_interrupt_isr_level near cyg_scheduler_sched_lock so that once one gets hit the other is already cached?

#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
   !defined(CYGPKG_HAL_SMP_SUPPORT)
   # Increment scheduler lock
   .extern cyg_scheduler_sched_lock
   incl    cyg_scheduler_sched_lock
#endif

I did run tm_basic with and without this code, and with additional asserts in the actual real-time clock to verify this is working. And there was practically no difference. (However, I was running on a non-caching Pentium 166, so it is probably not a fair test.)

There's no operational reason for eCos to need to keep track of this
stuff so I don't think it should be part of eCos. If you want to keep
track of interrupt or DSR calls, they can do this in application
code. Each ISR and DSR can increment/decrement the counters as
appropriate.



We discussed this, but really would prefer the OS to provide it so that all interrupt functions automatically have this. We may revert to it, if we cannot find a suitable solution.

There are other ways of detecting whether you are in an ISR. For
example by comparing the address of a local variable with the range of
the interrupt stack.


This will only work if CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK is enabled. Although we have not evaluated the correct setting for this option in our application, I am inclined to think that we will probably turn it off. Our thread stacks are "huge" since we have plenty of RAM. And wouldn't the existing stack have a better chance of cache hitting than a recently switched in stack? However, if I do add this, can I add an inline function to return a cyg_bool for in interrupt context in intr.hxx? Or should I create a new file intr.inl? (Or do you want me to just put it in my application?)

What does your custom print do that diag_printf() cannot? I would
question any system design that required any kind of printing from
ISRs.


First, I don't think diag_printf is callable in interrupt context. The primary function that "may" print in an ISR is an assert on a protected array. Normally our custom assert performs these functions:
1. Sets a global variable so our real-world outputs turn off. (This is assisted by an external watchdog in case the processor never gets back to do this.)
2. Prints the assert message to console.
3. Writes the same message into SRAM so it can be printed on next power-up.
4. Sends the message to our centralized messaging system. (This is queued and requires a semaphore.)
5. Put the current thread to sleep.
In interrupt context, we cannot print to the console, send the message to our message system and put the current thread to sleep. Under VxWorks, we also had to check for interrupt context before trying to get the current system date/time for messages, because that function would not work correctly under interrupt context. (I have not played with this yet under eCos.)
Yes we pay a huge performance penalty if an assert fires in interrupt context. But the bottom line is, we don't want the application to completely lock up when that happens, because we can get some useful information out of it through our diagnostic program. Also, since we have killed our real-world IO, the real-time requirements are no longer requirements.


Of course you are free to make any changes to the HAL and the rest of
eCos in your own sources. However, I'm not happy about accepting this
back into the main sources.



Fair enough, but can I ask if the patch looks technically correct? I really don't completely understand the layering of the VSR/ISR. Do all interrupts go through the VSR? And I could not declare _cyg_kernel_interrupt_isr_level the same as cyg_scheduler_sched_lock was declared (the schedule lock is declared static, but when I did that, the linker could not find it.)
Also, since this is configurable, isn't it pretty harmless unless someone needs it. Then they can evaluate the implications. (But thanks for the heads up about the caching issue. I will be sure to test that.)


David


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]