Because of object orientation Java requires runtime overhead even for conceptually simple tasks like interrupt handling. An interrupt service routine (ISR) in Java (RTCE) is implemented similar to a thread. A work() method has to be implemented in a subclass of ISRTask. The interrupt number is a member variable of this class. There can be several instances of the same class handling different interrupts.
To access member variables in the C translation of the ISRTask a pointer to the corresponding object has to be known inside the translated work() method.
In real-time operating systems ISRs are assigned to a hardware interrupt by a system call. This call has only two parameters: the interrupt number and the address of the handler method. In RTLinux it would look like this:
rtl_request_irq(irnumber, handler);Of course it is not possible to pass arguments to the handler method because it will be called by the underlying operating system. Therefore the interrupt handler has to get the object pointer from somewhere else. In the JaRTS runtime environment there is a wrapper function for all interrupt handlers fetching an object pointer of the corresponding ISRTask object from a small table whenever an interrupt occurs. This wrapper is used for all interrupts handled by Core Java applications. Roughly the wrapper function looks like this (some details left out):
void isr_entry(int irq) { isr_object* o=table[irq]; (o->methods->work)(o); }This is connected to every handled interrupt by
rtl_request_irq(irnumber, isr_entry);The object pointers are written to the table during initialization of the ISRTask. Accessing the table (table[]) does not require mutual exclusion because it will not be reallocated and values are only read (after the initialization phase where the handler will not be called with the current interrupt number).
So the Java overhead for ISRs is the table access and an additional function call in the isr_entry() function. This leads to slightly longer interrupt latencies compared to C but this is a predictable worst-case time. This time can be calculated by looking at the (assembly language) output of the C compiler with the assumption that all data and the code of the work() method is not in cache.