Event tables contain Events. Each event represents event
instances which might happen and could be handled.
<Off event. >= (U->)
// An event, it could be a trap, an interrupt, ...
class off_Event: public off_HWResUnit {
public:
// Sets h as the handler for this event
void set_handler(off_EventHandler *h);
// Gets the handler.
off_EventHandler *get_handler(void) const;
<Other public methods of off_Event. >
protected:
<Other protected methods of off_Event. >
private:
<Other private members of off_Event. >
};
Definesoff_Event(links are to index).
<Off event dependencies. >= (U->) [D->] #include <klib/HWResUnit.h> // for off_HWResUnit
A reference to the handler is kept in a member.
<Other private members of off_Event. >= (<-U) [D->]
off_EventHandler *ev_hndlr; // Event handler.
<off_Event::set_handler implementation. >= (U->)
// Sets h as the handler for this event
void off_Event::set_handler(off_EventHandler *h)
{
ev_hndlr=h;
}
<off_Event::get_handler implementation. >= (U->)
// Gets the handler.
off_EventHandler *off_Event::get_handler(void) const
{
return ev_hndlr;
}
In turn, events may be either Traps or Irqs (interrupts).
<Off Trap. >= (U->)
class off_Trap: public off_Event {
public:
<Other public methods of off_Trap. >
protected:
<Other protected methods of off_Trap. >
private:
<Other private members of off_Trap. >
};
Definesoff_Trap(links are to index).
<Off Irq. >= (U->)
class off_Irq: public off_Event {
public:
<Other public methods of off_Irq. >
protected:
<Other protected methods of off_Irq. >
private:
<Other private members of off_Irq. >
};
Definesoff_Irq(links are to index).
<Off event dependencies. >+= (U->) [<-D->] class off_EventTbl; class off_IntTbl; class off_TrapTbl;
<Off event implementation dependencies. >= (U->) #include <hw/EventTbl.h> // for off_IntTbl and off_TrapTbl
An event is created with a prespecified protection and domain identifier. A handler can be specified. The event itself cannot be instantiated, only traps and interrupts can.
<Other protected methods of off_Event. >= (<-U) [D->]
// Creates an event.
off_Event(const off_Protection &p,
const off_prtl_id_t &domain,
const off_ev_id_t &id,
const off_magic_t &magic,
off_EventTbl *evtbl,
const off_EventHandler *h );
<off_Event::off_Eventimplementation. >= (U->) [D->] // Creates an event. off_Event::off_Event(const off_Protection &p, const off_prtl_id_t &domain, const off_ev_id_t &id, const off_magic_t &magic, off_EventTbl *evtbl, const off_EventHandler *h ) : off_HWResUnit(p,domain,id,magic,(off_HWCompResource*)evtbl), ev_hndlr(h), <Initialize other aggregate members ofoff_Event. > {;}
<Other public methods of off_Trap. >= (<-U) [D->]
// Creates a trap.
off_Trap(const off_Protection &p,
const off_prtl_id_t &domain,
const off_ev_id_t &id,
off_TrapTbl *evtbl,
const off_EventHandler *h ) :
off_Event(p,domain,id,OFF_MAGIC_TRAP,(off_EventTbl*)evtbl,h)
{;}
<Other public methods of off_Irq. >= (<-U) [D->]
// Creates an interrupt.
off_Irq(const off_Protection &p,
const off_prtl_id_t &domain,
const off_ev_id_t &id,
off_IntTbl *evtbl,
const off_EventHandler *h ) :
off_Event(p,domain,id,OFF_MAGIC_IRQ,(off_EventTbl*)evtbl,h)
{;}
Users use a constructor receiving only the protection, the domain, and the handler to be set for the event being allocated.
<Other protected methods of off_Event. >+= (<-U) [<-D->]
// Creates an event.
off_Event(const off_Protection &p,
const off_prtl_id_t &domain,
const off_EventHandler *h );
<off_Event::off_Eventimplementation. >+= (U->) [<-D->] // Creates an Event. off_Event::off_Event(const off_Protection &p, const off_prtl_id_t &domain, const off_EventHandler *h ) : off_HWResUnit(p,domain), ev_hndlr(h), <Initialize other aggregate members ofoff_Event. > {;}
<Other public methods of off_Trap. >+= (<-U) [<-D->]
// Creates a trap.
off_Trap(const off_Protection &p,
const off_prtl_id_t &domain,
const off_EventHandler *h ) :
off_Event(p,domain,h)
{;}
<Other public methods of off_Irq. >+= (<-U) [<-D->]
// Creates an interrupt.
off_Irq(const off_Protection &p,
const off_prtl_id_t &domain,
const off_EventHandler *h );
When interrupts are created they are also enabled so that the hardware could deliver them.
<off_Irq::off_Irqimplementation. >= (U->) // Creates an interrupt. off_Irq::off_Irq(const off_Protection &p, const off_prtl_id_t &domain, const off_EventHandler *h ) : off_Event(p,domain,h), <Initialize other aggregate members ofoff_Irq. > { mask(); }
An interrupt destructor will disable it.
<Other public methods of off_Irq. >+= (<-U) [<-D->]
// Destroyes an interrupt.
virtual ~off_Irq(void);
<off_Irq::~off_Irq implementation. >= (U->)
// Destroyes an interrupt.
off_Irq::~off_Irq(void)
{
set_domain(OFF_PRTL_NULL); // Just to be sure.
protect(off_Protection());
mask();
}
Remaining event data is pre-initialized. First, a zero-argument (trap and interrupt) constructor permits declaration of uninitialized events.
<Other protected methods of off_Event. >+= (<-U) [<-D->]
// Allows uninitialized events.
off_Event(off_magic_t m);
It sets default values (the magic number must be supplied by concrete subclasses).
<off_Event::off_Eventimplementation. >+= (U->) [<-D->] // Allows uninitialized events. off_Event::off_Event(off_magic_t m) : off_HWResUnit(off_Protection(), OFF_PRTL_NULL, OFF_EU_ID_NULL, m, NULL), ev_hndlr(NULL), <Initialize other aggregate members ofoff_Event. > {;}
<Other public methods of off_Trap. >+= (<-U) [<-D->]
// Allows uninitialized traps.
off_Trap(void) : off_Event(OFF_MAGIC_TRAP) {;}
<Other public methods of off_Irq. >+= (<-U) [<-D->]
// Allows uninitialized interrupts.
off_Irq(void) : off_Event(OFF_MAGIC_IRQ) {;}
Note how initially every event has a null handler. Such handler is also reset to be null on event destruction.
<Other public methods of off_Event. >= (<-U) [D->]
virtual ~off_Event(void);
<off_Event::~off_Event implementation. >= (U->)
off_Event::~off_Event(void)
{
ev_hndlr=NULL;
}
When event tables are being created, another constructor is used to pre-initialize those event fields which are unlikely to change.
<Other protected methods of off_Event. >+= (<-U) [<-D]
// Pre-initializes an event.
off_Event(const off_ev_id_t &id, const off_magic_t &m,
off_EventTbl *c, off_EventHandler *h);
Note how in this case (unlike other hardware resource units) we make a provision for a default handler to be installed. Such handler will notify than an stray event has appeared and do nothing else.
<off_Event::off_Eventimplementation. >+= (U->) [<-D] // Pre-initializes an event. off_Event::off_Event(const off_ev_id_t &id, const off_magic_t &m, off_EventTbl *c, off_EventHandler *h) : off_HWResUnit(id,m,(off_HWCompResource*)c), ev_hndlr(h), <Initialize other aggregate members ofoff_Event. > {;}
<Other public methods of off_Irq. >+= (<-U) [<-D->]
// Pre-initializes an interrupt.
off_Irq(const off_ev_id_t &id, off_IntTbl *c, off_EventHandler *h) :
off_Event(id,OFF_MAGIC_IRQ,(off_EventTbl*)c,h)
{;}
<Other public methods of off_Trap. >+= (<-U) [<-D->]
// Pre-initializes a trap.
off_Trap(const off_ev_id_t &id, off_TrapTbl *c, off_EventHandler *h) :
off_Event(id,OFF_MAGIC_TRAP,(off_EventTbl*)c,h)
{;}
We have to define the magic numbers used.
<Off magic numbers. >+= [<-D] OFF_MAGIC_TRAP, // Interrupt table magic nb. OFF_MAGIC_IRQ, // Trap table magic nb.
We can now add another couple of cases to the implementation of
Magic::nameof.
<off_Magic::nameofcase form_numbers. >+= [<-D] case OFF_MAGIC_TRAP: return "off_Trap"; case OFF_MAGIC_IRQ: return "off_Irq";
Event users can check their references using these methods.
<Other public methods of off_Trap. >+= (<-U) [<-D->]
// Does this look like a Trap?
boolean_t valid(void) const { return get_magic() == OFF_MAGIC_TRAP; }
<Other public methods of off_Irq. >+= (<-U) [<-D->]
// Does this look like a Irq?
boolean_t valid(void) const { return get_magic() == OFF_MAGIC_IRQ; }
And containers can now implement their get_umagic methods.
<Other protected methods of off_TrapTbl. >= (<-U)
virtual off_magic_t get_umagic(void) { return OFF_MAGIC_TRAP; }
<Other protected methods of off_IntTbl. >= (<-U)
virtual off_magic_t get_umagic(void) { return OFF_MAGIC_IRQ; }
<Off event dependencies. >+= (U->) [<-D->] #include <assert.h> // for assert