next up previous contents
Next: 4.1.5 Event allocation Up: 4.1 Input/Output Previous: 4.1.3 Event tables

4.1.4 Events

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. >
};
Defines off_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. >
};
Defines off_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. >
};
Defines off_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_Event implementation. >= (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 of off_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_Event implementation. >+= (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 of off_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_Irq implementation. >= (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 of off_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_Event implementation. >+= (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 of off_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_Event implementation. >+= (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 of off_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::nameof case for m_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


next up previous contents
Next: 4.1.5 Event allocation Up: 4.1 Input/Output Previous: 4.1.3 Event tables
Francisco J. Ballesteros
1998-05-25