What you really want is the variable visibility and restrictions
found by using nested procedures, as in Pascal. The best
approximation of this you can get in C involves using separate
files and static file scope variables. This has the disadvantage
that things that should really be automatic aren't, so that their
memory is not released when not needed, and the simultaneous
advantage that routines and variables can be global to multiple
functions.
Won't help really. The project was an OS for a special kind of
processor family.
About 4,000,000 lines of code in about 400 modules. And a team of 40
developers working together.
Enty gate: user API calls comes here in
IRQ gate : IRQ comes her in and gets dispatched to its real sourse
This was done because an IRQ was commony coming from an
multiple cascaded hardware interface (256 * 256 * n)
devices on one.
So each of the entry points had either to call some functions with 2
to 200 parameters or to put anything on static places and make the
call parameterless. Parameterless calls are cheap in runtime, up tu 4
parameters are normal and more parameters were really expensive in a
call. So saving parameters was the main point to get runtime save
functionality.
There were 4 differen address spaces to handle:
- user addressroom data
- user addressroom code
- OS internal addressroom data
- OS internal addressroom code
Each addressroom was limited to 64 KB. Swappig addressroom was really
expensive on CPU, so the call cate had to collect the parameters from
user addressroom, store them inside the OS addressroom (including data
coming in as pointers, but excluding disk and other media buffers) to
save any driver and fuction to catch them theyrself.
But as that there were some experienced programmers who were crying
that global data is evil. Yes global data IS evil - but inside an OS
performance is more relevant than avoiding globals. Breaking code in
deep levels of functions, breaking it up in different translation
units is standard - even inside an OS. Has nothing to do with pascal -
except that pascal is unable to translate multiple soursec seapartele
and bind statically with assembler modules.
At the same time such usage makes the routines non-reentrant and
non-thread-safe, due to the lack of automatic storage for the
variables.
Threadsave is impossible when you have exactly one interrupt level you
runs in and this is the highest below NMI and hardware IRQ level. So a
call from a user runs exclusive on the CPU until it comes back to the
user gate that gives the CPU back to a user function - except an NMI
or hardware IRQ occures. So saving CPU time is most critical in an
realtime OS to let all CPU ever possible the user.