Each Distributed Memory Manager (DMM, for short) is actually a pool of DTLBs. However, DTLBs are an optional feature. Machines dedicated to a single application (like a dedicated file server, an embedded controller, etc.) can use a single protection domain for efficiency purposes.
A DMM multiplexes the address translation hardware among the existing DTLBs in cooperation with the shuttle server (as there is usually one processor register used to identify the protection domain). Hence, the DMM includes a DTLB allocator to provide DTLBs.
<Off DMM. >=
// An dtlb server (distributed memory manager).
//
class off_DMM : public off_AbsCompResource {
public:
// Returns a pointer to the shuttle allocator.
virtual off_DTLBAllocator *get_allocator(void);
// Returns a reference to a dtlb from its distributed or physical
// address.
inline off_DTLB *operator +(vm_offset_t d);
<Other public methods of off_DMM. >
<off_DMM shuttle property methods. >
protected:
<Other protected methods of off_DMM. >
private:
static off_DTLBAllocator d_alloc; // dtlb allocator
};
Definesoff_DMM(links are to index).
<Off DMM dependencies. >= [D->] #include <klib/AbsCompResource.h> // for off_AbsCompResource #include <dmm/DMMAllocator.h> #include <dmm/DTLB.h> // for off_DTLB
<Off DMM static members. >= off_DTLBAllocator off_DMM::d_alloc; // dtlb allocator
<off_DMM::get_allocator implementation. >=
inline off_DTLBAllocator *off_DMM::get_allocator(void) {
assert(valid()); return &d_alloc;
}
Being a subclass of CompResource we must implement
make_available and is_local.
<Other public methods of off_DMM. >= (<-U) [D->]
// We may wish to cache a resource unit.
// Returns error code if the resource is not available. Zero otherwise.
inline err_t make_available(off_id_t &u);
<off_DMM::make_availableimplementation. >= // We may wish to cache a resource unit. // Returns error code if the resource is not available. Zero otherwise. inline err_t off_DMM::make_available(off_id_t &u) { <Body ofoff_CompResource::make_available. > }
<Other public methods of off_DMM. >+= (<-U) [<-D->]
// Is this identifier a local one?
inline boolean_t is_local(const off_dtlb_id_t &d);
<off_DMM::is_local implementation. >=
// Is this identifier a local one?
inline boolean_t off_DMM::is_local(const off_dtlb_id_t &d)
{
return ( d.i_slot <= d_alloc.get_length() &&
(d_alloc+(natural_t)d.i_slot)->get_id() == d );
}
<Off DMM dependencies. >+= [<-D->] #include <klib/ids.h> // for OFF_PRTL_NULL et al. #include <flux/types.h> // for boolean_t natural_t et al. #include <klib/err.h> // for err_t #include <klib/prot.h> // for off_Protection #include <klib/Magic.h> // for magic numbers
The \dmm{} is created with default values for its members and will
remain in a dormant state until DTLB support is started (if ever)
by calling the DMM start method.
<Other public methods of off_DMM. >+= (<-U) [<-D->]
// Creates a DMM.
off_DMM(void);
<off_DMM::off_DMMimplementation. >= // Creates a DMM. off_DMM(void) : off_HWCompResource(off_Protection(),OFF_PRTL_NULL, OFF_ID_NULL, OFF_MAGIC_DMM), <Initialize other aggregate members ofoff_DMM. > {;}
<Off DMM dependencies. >+= [<-D->] #include <klib/prot.h> // for off_Protection #include <klib/err.h> // for err_t and error numbers. #include <klib/Magic.h> // for magic numbers #include <klib/HWCompResource.h> // for off_HWCompResource #include <dmm/DTLBAllocator.h> // for off_IOAllocator et al. #include <dmm/DTLB.h> // for off_IOPort et al.
There is a single \dmm{} instance per system.
<Off DMM exported variables. >= extern off_DMM dmm; // DMM instance for this node.
<Off DMM global variables. >= off_DMM dmm; // DMM instance for this node.
We must define the new magic number used before.
<Off magic numbers. >= [D->] OFF_MAGIC_DMM, // DMM magic nb.
We can now add another case to the implementation of
Magic::nameof.
<off_Magic::nameofcase form_numbers. >= [D->] case OFF_MAGIC_DMM: return "off_DMM";
\dmm{} users can check their references to \dtlb{} banks using this method.
<Other public methods of off_DMM. >+= (<-U) [<-D->]
// Does this look like a DMM?
boolean_t valid(void) const { return get_magic() == OFF_MAGIC_DMM; }
The new container can also implement its get_umagic method.
<Other protected methods of off_DMM. >= (<-U) [D->]
virtual off_magic_t get_umagic(void) { return OFF_MAGIC_DTLB; }
After instantiation, start should be used to start DMM
operation.
<Other public methods of off_DMM. >+= (<-U) [<-D->]
// Starts normal operation for this DMM.
err_t start(const off_mdepDMM &mdep, const off_id_t &id );
<Off DMM dependencies. >+= [<-D->] #include <dmm/mdep/mDMM.h> // for off_mdepDMM
<off_DMM::startimplementation. >= // Starts normal operation for this DMM err_t off_DMM::start( const off_mdepDMM &mdep, const off_id_t &id ) { assert(valid()); set_id(id); <Initialized_alloc. > <Start other members ofoff_DMMaccording tomdep. > kcout<< "DMM #" << id << " started." << nl; return EOK; }
<Off DMM dependencies. >+= [<-D] #include <assert.h> // for assert #include <klib/str.h> // for kcout.
A new member, d_mdep stores any boot time machine dependent
information which might be needed by the dmm.
<Other private members of off_DMM. >= [D->]
off_mdepDMM d_mdep; // Machine dependent info.
<Start other members ofoff_DMMaccording tomdep. >= (<-U) d_mdep=mdep;
Initially, before it is started, it is initialized with default values.
<Initialize other aggregate members of off_DMM. >= (<-U)
d_mdep(0),