next up previous contents
Next: 4.1.4 Events Up: 4.1 Input/Output Previous: 4.1.2 Input/Output for plain

4.1.3 Event tables

Both traps and interrupts are allocated using per-processor event tables. Each processor has associated a trap and interrupt tables. Traps may be caused by the hardware or by the kernel itself. Software interrupts are also available.

<Off event table. >= (U->)
// An event table 
//
class off_EventTbl : public off_HWCompResource {
public:
  <Other public methods of off_EventTbl. >
protected:
  <Other protected methods of off_EventTbl. >
};

Defines off_EventTbl (links are to index).

Event tables cannot be instantiated, the only have a pass-by constructor to initialize HWCompResource state.

<Other protected methods of off_EventTbl. >= (<-U) [D->]
// Creates an event table. 
off_EventTbl(const off_Protection &p, 
             const off_prtl_id_t &domain,
             const off_prtl_id_t &id,
             const off_magic_t magic ):
  off_HWCompResource(p,domain,id,magic) 
{;}

By now we have these dependencies.

<Off event table dependencies. >= (U->) [D->]
#include <klib/ids.h>            // for off_ev_id_t
#include <klib/HWCompResource.h> // for off_HWCompResource
#include <klib/prot.h>          // for off_Protection
#include <klib/Magic.h>         // for magic numbers

There are two concrete subclasses of event tables: trap and interrupt tables. These ones can be instantiated to operate on a given processor or shuttle (just for trap tables). Such tables use trap and interrupt allocators to allocate their events.

<Off trap table. >= (U->)
// Definition of traps for the current processor
//
class off_TrapTbl: public off_EventTbl {
public:
  // Creates a trap table.
  off_TrapTbl(off_Processor *proc);
  //  off_TrapTbl(const off_Shtl      &shtl);         XXX fix this

  // Returns the allocator being used.
  off_TrapAllocator *get_allocator(void);

  <Other public methods of off_TrapTbl. >
protected:
  <Other protected methods of off_TrapTbl. >
private:
  off_TrapAllocator t_alloc;    // allocator for traps. 
  <Other private members of off_TrapTbl. >

};

Defines off_TrapTbl (links are to index).

<Off event table dependencies. >+= (U->) [<-D->]
#include <hw/Event.h>           // for off_Trap, off_Irq, off_Event et al.

<Off interrupt table. >= (U->)
// Definition of interrupts for the current processor.
//
class off_IntTbl: public off_EventTbl {
public:
  // Creates an interrupt table.
  off_IntTbl(off_Processor *proc);

  // Returns the allocator being used.
  off_IntAllocator *get_allocator(void);

  <Other public methods of off_IntTbl. >
protected:
  <Other protected methods of off_IntTbl. >
private:
  off_IntAllocator i_alloc;    // allocator for interrupts. 
  <Other private members of off_IntTbl. >
};
Defines off_IntTbl (links are to index).

Trap and interrupt tables are created using the protection, domain, and identifier of the processor (or shuttle) being used.

<off_TrapTbl::off_TrapTbl implementation. >= (U->)
// Creates a trap table.
off_TrapTbl::off_TrapTbl(off_Processor *proc) :
   off_EventTbl(proc->get_protection(), proc->get_domain(), 
                proc->get_id(), OFF_MAGIC_TRPTBL),
   <Initialize t_alloc. >,
   <Initialize other aggregate members of off_TrapTbl. >
{;}

#if 0                           // XXX fix this
// Creates a trap table.
off_TrapTbl::off_TrapTbl(const off_Shtl &s) :
   off_EventTbl(s.get_protection(), s.get_domain(), 
                s.get_id(), OFF_MAGIC_TRPTBL),
   <Initialize t_alloc. >,
   <Initialize other aggregate members of off_TrapTbl. >
{;}
#endif

Interrupt tables can be only attached to processors, as a shuttle should not have control on how interrupts happening in its quanta are handled.

<off_IntTbl::off_IntTbl implementation. >= (U->)
// Creates an interrupt table.
off_IntTbl::off_IntTbl(off_Processor *proc) :
  off_EventTbl(proc->get_protection(), proc->get_domain(),
               proc->get_id(), OFF_MAGIC_INTTBL),
  <Initialize i_alloc. >,
  i_proc(proc),
  <Initialize other aggregate members of off_IntTbl. >
{ ;}

The interrupt table maintains a reference to the processor being used, as we have seen.

<Other private members of off_IntTbl. >= (<-U) [D->]
off_Processor *i_proc;          // processor

<Off event table dependencies. >+= (U->) [<-D->]
#include <hw/EvAllocator.h>     // for off_{Trap,Int}Allocator
class off_Processor;
//class off_Shtl;    XXX fix this

<Off event table late dependencies. >=
#include <hw/Processor.h>       // for off_Processor
/* # include <shtl/Shtl.h>          // for off_Shtl XXX fix this */

We must define the new magic numbers used before.

<Off magic numbers. >= [D->]
OFF_MAGIC_INTTBL,               // Interrupt table magic nb.
OFF_MAGIC_TRPTBL,               // 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_INTTBL:
  return "off_IntTbl";
case OFF_MAGIC_TRPTBL:
  return "off_TrapTbl";

Event table users can check their references using these methods.

<Other public methods of off_TrapTbl. >= (<-U) [D->]
// Does this look like a TrapTbl?
boolean_t valid(void) const { return get_magic() == OFF_MAGIC_TRPTBL; }

<Other public methods of off_IntTbl. >= (<-U) [D->]
// Does this look like a IntTbl?
boolean_t valid(void) const { return get_magic() == OFF_MAGIC_INTTBL; }

<Other public methods of off_IntTbl. >+= (<-U) [<-D->]
// Is this identifier a local one?
inline boolean_t is_local(const off_ev_id_t &ev);

<Other public methods of off_TrapTbl. >+= (<-U) [<-D->]
// Is this identifier a local one?
inline boolean_t is_local(const off_ev_id_t &ev);

As any other CompResource, trap and interrupt tables implement make_available and is_local.

<Other public methods of off_IntTbl. >+= (<-U) [<-D->]
<Implementation of off_CompResource::make_available. >

<Other public methods of off_TrapTbl. >+= (<-U) [<-D->]
<Implementation of off_CompResource::make_available. >

<off_IntTbl::is_local implementation. >= (U->)
// Is this identifier a local one?
inline boolean_t off_IntTbl::is_local(const off_ev_id_t &ev) 
{
    return ( ev.i_slot <= i_alloc.get_length() &&
             (i_alloc+(natural_t)ev.i_slot)->get_id() == ev );

}

<off_TrapTbl::is_local implementation. >= (U->)
// Is this identifier a local one?
inline boolean_t off_TrapTbl::is_local(const off_ev_id_t &ev) 
{
    return ( ev.i_slot <= t_alloc.get_length() &&
             (t_alloc+(natural_t)ev.i_slot)->get_id() == ev );

}

<Off event table dependencies. >+= (U->) [<-D->]
#include <flux/types.h>         // for boolean_t natural_t et al.

We will be seeing other features of event tables while we discuss events.



Francisco J. Ballesteros
1998-05-25