This is the mail archive of the
crossgcc@cygnus.com
mailing list for the crossgcc project.
Re: Code Gen problem calling functions through pointers.
>>>>> "David" == David Querbach <querbach@realtime.bc.ca> writes:
>> Is it *ENTIRELY* in C++? Is it pre-emptive? If so, how do you
>> do context save and restore operations in C++ in a machine
>> transparent manner?
David> Perhaps I should have said "C/C++". We use setjmp/longjmp
David> for context switching, and have added a function we call
David> "initjmp" to prime a jmpbuf when first creating a task. We
David> of course use a few classic C functions such as strcpy,
David> strlen, and the transcendental math functions.
David> Yes, it is fully pre-emptive, with a sub-100 usec interrupt
David> latency on reasonable (16 and 32-bit) micros.
This seems rather slow to me, but it all depends on the cpu you are
using. With a modern 32 bit cpu running what I would call reasonable
speeds, I would expect considerably better than this. Or did you mean
100 ns instead of 100 us?
I wrote an exec for a special 32 bit cpu that had 2 copies of that cpu
in a single custom asic a few years back. The cpu speed was 54 MHz,
or 18.5 ns/clock, and I was able to switch context from one task to
another, passing thru the exec, in 66 clocks, or 1.221 us, with a
maximum interrupt latency of 11 clocks, or 203.5 ns.
This cpu was optimized to run threaded interpretive languages, such as
Forth. The exec was written in ANSI Forth with the assembler routines
SLEEP and WAKE to save and restore context.
Now consider what these times would be at modern clock speeds of 400
MHz: 165 ns context switch, and 27.5 ns interrupt latency! WOW!
I wrote the cross compiler for this machine also, and there was some
room to improve the optimization going from Forth to the machine's
internal representation, but I did not have time to persue that angle.
David> Only the system startup, first-level interrupt handler, and
David> global interrupt masking are in assembler. The system
David> startup consists of a few hundred lines to initialize the
David> .bss and .data sections, call the static constructors, and
David> call main().
David> The first-level interrupt handler varies in its
David> implementation according to the way interrupts are handled
David> on a given processor, but it always looks in a static table
David> of interrupt handler objects:
David> The first level interrupt handler's job is to look up the
David> Isr-derived object for the current interrupt, call its
David> virtual handler() function, then return from interrupt.
It looks like you are using a linked list to maintain the handlers.
Perhaps the lookup time to find the proper handler is a major time
eater?
--
-------- "And there came a writing to him from Elijah" [2Ch 21:12] --------
R. J. Brown III rj@elilabs.com http://www.elilabs.com/~rj voice 847 543-4060
Elijah Laboratories Inc. 457 Signal Lane, Grayslake IL 60030 fax 847 543-4061
----- M o d e l i n g t h e M e t h o d s o f t h e M i n d ------
_______________________________________________
New CrossGCC FAQ: http://www.objsw.com/CrossGCC
_______________________________________________
To remove yourself from the crossgcc list, send
mail to crossgcc-request@cygnus.com with the
text 'unsubscribe' (without the quotes) in the
body of the message.