OSCL was originally conceived around 1995. Since then it has grown
significantly as more components have been added and existing components
have evolved. The evolutionary aspect is a form of refactoring. With
practice and time, experience results in a deeper understanding of many
issues. Recently, with an increased desire towards putting the OSCL into
the wild, I've also discovered some areas that I feel need refactoring.
Since much of the OSCL is quite low-level, I feel that some of this
foundational work needs to be done before OSCL is released into the
wild, to stave off bit rot.
The areas that are ripe for refactoring include things as mundane as
naming. I feel that choosing good names is important for clarity. I also
feel that consistency in naming is important to users of the OSCL when
searching for components to reuse.
This document serves the purpose as a place holder for these
refactoring ideas until I can get around to implementing them.
Application and Platform Layering
The initial concept of the OSCL assumed a broad porting layer that
defined all low-level interfaces that are platform specific (e.g.
compiler, processor, and target.) Things are never as simple as they
seem. As I developed OOOS and various drivers for the PowerPC family, I
discovered that it demanded more from this layer, and indeed that the
PowerPC architecture itself allowed for many variations. In other words,
there is no such thing as the PowerPC platform. More generally, I have
become aware of issues with regards to processor subsystems, especially
cache properties, atomic operations, in-order execution, pipeline
synchronization and similar issues that affect the ability to write
portable drivers.
All this has led me to look at the various layers and their
dependencies. Presently, I envision two major layering systems:
- Application/Framework
- Hardware
Of course, the application related layers ultimately depend upon the
lower level hardware layer.
The hardware layer is organized into several sub layers:
- Memory Map (RAM,ROM,Peripherals,DMA bus conversions)
- MMU (Page size, attributes, conversions)
- Cache (Cache line size, flush and invalidate)
- Processor Mode (e.g. Some processors can be big or little endian,
the H8 can have different sized general purpose registers)
- Processor (Interrupt enable/disable, supervisor instructions)
- Compiler (For particular processor,data sizes, assembler syntax)
The application/framework layer is organized into these sub layers:
- Application
- Drivers / Frameworks
- ITC Model (Communications Model)
- Multi Threading (Semaphores, Scheduling) (OOOS, POSIX,VxWorks)
- Asynchronous Control (Signals/Interrupts)
Naming
Rework/split/reorganize/refactor current platform structure including:
- Target
- Platform
- mt/platform
- ooos/platform
As a part of this re-factoring, I'm going to place plaform inlines
under the "Oscl" for consistency, and each new catagory will have a
sub-namespace underneath. E.g. Oscl::Compiler::Unsigned16, and
Oscl::AsyncExec::DisableAsyncExecution().
Since the OSCL and ITC in particular, may be used in both kernel and
user-space, I want to rename the functions that enable and disable
"interrupts." Indeed, the term "interrupt" implies a kernel-space
concept, whereas in user-space the actual entity disabled are signals to
the process. I'm looking for a more abstract name to encompass these two
concepts. Currently the disable function is called
PlatSupervisorDisableInterruptions(). I'm considering calling the
concept "AsyncExecution" and thus this disable operation might be called
PlatDisableAsyncExecution().
PlatIntLevel
Asside from renaming and reorganizing these functions, I need to change
the signatures from this:
PlatIntLevel PlatSupervisorDisableInterruptions(void);
PlatIntLevel PlatAquireGlobalMpInterruptLock(void);
void PlatSupervisorRestoreInterruptions(PlatIntLevel saved);
void PlatReleaseGlobalMpInterruptLock(PlatIntLevel saved);
to:
void PlatSupervisorDisableInterruptions(PlatIntLevel& saved);
void PlatAquireGlobalMpInterruptLock(PlatIntLevel& saved);
void PlatSupervisorRestoreInterruptions(const PlatIntLevel& saved);
void PlatReleaseGlobalMpInterruptLock(const PlatIntLevel& saved);
This change allows for
PlatIntLevel
types to be
structures. The motivation for this change is the usage in a POSIX
user-space implementation, where signals must be enabled/disabled using
sigprocmask(sigset_t*
mask)
where the type
sigset_t
becomes
typedef
ed
to
PlatIntLevel.
BTW, "Acquire"
is spelled wrong in
PlatAquireGlobalMpInterruptLock
.
I believe that the candidate for
DisableAsyncExecution
is
probably
PlatAquireGlobalMpInterruptLock()
, and its
oposite. The others are very processor specific and for a layer that is
below the
DisableAsyncExecution
interface.