The node navigator gives access to every resource container in the local node.
<Off node navigator. >= (U->)
// A node navigator.
//
class off_NodeNav : public off_Navigator {
private:
off_Node &n_nd;
<Other private members of off_NodeNav. >
public:
// Creates a node navigator.
off_NodeNav(off_Node &nd);
// Returns a reference to the resource being navigated
virtual off_Resource *get_current(void);
// Advances the iteration and returns the next element.
virtual off_CompResource *get_next(void);
// Resets the iteration so that get_next will return the 1st element.
virtual void reset(void);
// Selects a component by name.
virtual off_CompResource *operator[](const char *name);
virtual off_CompResource *operator[](const off_id_t &id);
};
Definesoff_NodeNav(links are to index).
<Off node navigator dependencies. >= (U->) [D->] #include <assert.h> // for assert #include <klib/ids.h> // for off_id_t et al. #include <klib/CompResource.h> // for off_CompResource. #include <klib/nav.h> // for off_Navigator. class off_Node; // to break circular dependency.
<Off node navigator late dependencies. >= (U->) #include <node/Node.h> // for off_Node.
The node navigator is generated dynamically every time it is needed using a simple constructor.
<off_NodeNav::off_NodeNavimplementation. >= (U->) // Creates a node navigator. off_NodeNav::off_NodeNav(off_Node &nd) : n_nd(nd), <Initialize other aggregate members ofoff_NodeNav. > { assert(nd.valid()); }
Now we can implement this method:
<Other public methods of off_Node. >+= (<-U) [<-D->]
off_Navigator *get_navigator(void) { return new off_NodeNav(*this); }
<Off node dependencies. >+= (U->) [<-D->] #include <klib/nav.h> // for off_Navigator #include <node/ndnav.h> // for off_NodeNav
Besides, this other one is fairly trivial too.
<off_NodeNav::get_current implementation. >= (U->)
// Returns a reference to the resource being navigated
off_Resource *off_NodeNav::get_current(void)
{
return &n_nd;
}
The key methods are reset and get_next. They use some members
to keep the iteration state.
<Other private members of off_NodeNav. >= (<-U)
enum {
N_MBANK=0,
N_IOBANK,
N_PROC,
// N_DMA,
N_SHTL,
// N_PRTL,
// N_DMM,
N_EXHAUST
};
natural_t n_resource; // resource kind being navigated inside n_nd.
natural_t n_pos; // resource nb.
boolean_t valid(void) const {
return n_resource <= N_EXHAUST; // It's always >=N_MBANK
}
<Initialize other aggregate members of off_NodeNav. >= (<-U)
n_resource(N_MBANK), n_pos(0)
The initial state is recovered by reset.
<off_NodeNav::reset implementation. >= (U->)
// Resets the iteration so that get_next will return the 1st element.
void off_NodeNav::reset(void)
{
n_resource=N_MBANK;
n_pos=0;
}
Iteration is advanced by get_next. It advances the iterator using
the node navigation methods.
<off_NodeNav::get_next implementation. >= (U->)
// Advances the iteration and returns the next element.
off_CompResource *off_NodeNav::get_next(void)
{
off_CompResource *res=NULL;
assert(valid());
switch(n_resource){
case N_MBANK:
if (n_pos==n_nd.get_num_mbanks()){
n_pos=0; n_resource++;
res= get_next();
}
else {
res=&n_nd.get_mbank(n_pos++);
break;
}
case N_IOBANK:
if (n_pos==n_nd.get_num_iobanks()){
n_pos=0; n_resource++;
res= get_next();
}
else
res=&n_nd.get_iobank(n_pos++);
break;
case N_PROC:
if (n_pos==n_nd.get_num_procs()){
n_pos=0; n_resource++;
res= get_next();
}
else
res=&n_nd.get_proc(n_pos++);
break;
#if 0 // XXX fix this
case N_DMA:
if (n_pos==n_nd.get_num_dmas()){
n_pos=0; n_resource++;
res= get_next();
}
else
res=&n_nd.get_dma(n_pos++);
break;
#endif // 0
case N_SHTL:
res=&n_nd.get_shtl();
n_resource++;
break;
#if 0
case N_PRTL:
res=&n_nd.get_prtl();
n_resource++;
break;
case N_DMM:
res=&n_nd.get_dmm();
n_resource++;
break;
#endif // 0
case N_EXHAUST:
break;
default:
panic("node nagivator: invalid resource id.");
}
return res;
}
<Off node navigator implementation dependencies. >= (U->) #include <flux/debug.h> // for otsan et al.
The last couple of iteration methods are implemented with those shown above.
<off_NodeNav::operator[] implementation. >= (U->) [D->]
// Selects a component by name.
off_CompResource *off_NodeNav::operator[](const char *name)
{
off_CompResource *res;
assert(name && valid());
reset();
while ( (res=get_next()) && strcmp(res->nameof(),name) )
;
return res;
}
<off_NodeNav::operator[] implementation. >+= (U->) [<-D]
// Selects a component by name.
off_CompResource *off_NodeNav::operator[](const off_id_t &id)
{
off_CompResource *res;
assert(valid());
reset();
while ( (res=get_next()) && res->get_id() != id )
;
return res;
}
\subsection{The node inspector}
The node inspector's attribute array looks like this:
<Off nd inspector attribute array initializer. >= (U->)
{ { OFF_STR_ATTR , "name", &off_Node::nameof },
{ OFF_STR_ATTR, "class", &off_Node::kindof },
{ OFF_ID_ATTR, "dom", &off_Node::get_domain },
{ OFF_ID_ATTR, "id", &off_Node::get_id },
{ OFF_STR_ATTR, "url", &off_Node::get_url },
{ OFF_STR_ATTR, "provides", &off_Node::nameof },
{ OFF_STR_ATTR, NULL, NULL }, // no requeriments.
// Node specific attributes.
{ OFF_STR_ATTR, "arch", &off_Node::get_arch }, // Architecture
{ OFF_STR_ATTR, "owner", &off_Node::get_owner }, // Owner's email
{ OFF_STR_ATTR, "kvers", &off_Node::get_kvers }, // Kernel version
{ OFF_NULL_ATTR, NULL, NULL } } // End of attribute list.
<Off node inspector attribute array length. >= (U->) const int OFF_NINSP_NATTR=10; // not counting final NULL attr.
We already knew many node attributes, only accessors for new node attributes must now be implemented.
<Other private members of off_Node. >= (<-U) [D->]
char *n_owner; // Node owner.
char *n_url; // Source code url
<Other public methods of off_Node. >+= (<-U) [<-D->]
// Get the node URL architecture and kernel version.
const char *get_url(void) { return n_url; }
const char *get_arch(void) const { return off_Version::arch; }
const char *get_kvers(void) const { return off_Version::version; }
const char *get_owner(void) const { return n_owner; }
<Off node dependencies. >+= (U->) [<-D->] #include <klib/Version.h> // for off_Version
The owner's email and source URL are initialized at boot time, when boot time options are processed. Initially they are set to null values.
<Initialize other private members of off_Node. >+= (<-U) [<-D->]
n_owner=n_url=NULL;
Given this attribute list, the node inspector is defined as follows
<Off node inspector. >= (U->)
// A node inspector.
//
class off_NodeInsp : public off_Inspector {
private:
static off_attr_t n_attrs[OFF_NINSP_NATTR+1]; // for final NULL attr.
public:
// Creates a node inspector.
off_NodeInsp(off_Node *nd);
};
Definesoff_NodeInsp(links are to index).
<Off node navigator dependencies. >+= (U->) [<-D] #include <assert.h> // for assert
Where the attribute array is shared.
<Off node inspector static members. >= (U->)
// inspector attributes for node.
off_attr_t off_NodeInsp::n_attrs[OFF_NINSP_NATTR+1] =
<Off nd inspector attribute array initializer. >
;
Every time get_inspector is called, a new inspector is
created. The user should delete it whenever it is no longer
needed.
<Other public methods of off_Node. >+= (<-U) [<-D->]
off_Inspector *get_inspector(void) {
return new off_NodeInsp(this);
}
The constructor is very simple.
<off_NodeInsp::off_NodeInsp implementation. >= (U->)
// Creates a node inspector.
off_NodeInsp::off_NodeInsp(off_Node *nd) :
off_Inspector(nd, n_attrs, OFF_NINSP_NATTR)
{
assert(nd && nd->valid());
}
\subsection{Node navigation \cpp{} source files}
The navigation code for nodes is kept in node/ndnav.h and
node/ndnav.C.
<ndnav.h*>= <Read the literate code instead warning. > #ifndef __OFF_NODE_NAV_H #define __OFF_NODE_NAV_H 1 <Off node navigator dependencies. > <Off node inspector attribute array length. > #ifdef __KERNEL__ <Off node navigator. > <Off node inspector. > #endif // __KERNEL__ <Off node navigator late dependencies. > #endif // __OFF_NODE_NAV_H
<ndnav.C*>= <Read the literate code instead warning. > #include <node/ndnav.h> // Exported interface. <Off node navigator implementation dependencies. > <Off node inspector static members. > <off_NodeNav::off_NodeNavimplementation. > <off_NodeInsp::off_NodeInspimplementation. > <off_NodeNav::get_currentimplementation. > <off_NodeNav::resetimplementation. > <off_NodeNav::get_nextimplementation. > <off_NodeNav::operator[]implementation. >
\section{Nodes for plain users}
The wrapper for node services export almost everything as can be seen.
<Off node for users. >= (U->)
// A Node for system users.
//
ENTRY class off_uNode : public off_uResource{
public:
#if 0 // XXX fix this
off_prtl_id_t get_auth(const off_Rights &r) const;
off_prtl_id_t get_xdt(const off_Rights &r) const;
err_t set_auth(const off_prtl_id_t p, const off_Rights &r);
err_t set_xdt(const off_prtl_id_t p, const off_Rights &r);
void halt( const char *msg );
void reboot( const off_Rights &r );
err_t suspend( const off_Rights &r );
// Returns the number of specific containers found at this node
natural_t get_num_mbanks(const off_Rights &r) const ;
// Returns a pointer to a local memory bank.
off_MBank &get_mbank( natural_t id = 0, const off_Rights &r);
// Return the number of specific containers found at this node
// Get a pointer to a hardware resource container
natural_t get_num_iobanks(const off_Rights &r) const;
off_IOBank &get_iobank( natural_t id=0, const off_Rights &r);
natural_t get_num_dmas(const off_Rights &r) const ;
off_DMA &get_dma( natural_t id=0, const off_Rights &r);
natural_t get_num_procs(const off_Rights &r) const;
off_Processor &get_proc( natural_t id=0, const off_Rights &r);
off_ShtlSrv &get_shtl( const off_Rights &r);
off_PrtlSrv &get_prtl( const off_Rights &r);
off_DMM &get_dmm( const off_Rights &r);
<Other public methods of off_uNode. >
#endif
};
Definesoff_uNode(links are to index).
\section{Node \cpp{} source files}
Main node definitions are found in node/Node.h. The implementation is
kept in node/Node.C.
<Node.h*>= <Read the literate code instead warning. > #ifndef __OFF_NODE_H #define __OFF_NODE_H 1 <Off node dependencies. > #ifdef __KERNEL__ <Off node. > <Off node exported variables. > #else // __KERNEL__ <Off node for users. > #endif // __KERNEL__ #endif // __OFF_NODE_H
<Node.C*>= <Read the literate code instead warning. > #define __OFF_NODE_C #include <node/Node.h> // Exported interface. <Off node implementation dependencies. > <Off node global variables. > <off_Node::haltimplementation. > <off_Node::rebootimplementation. > <off_Node::suspendimplementation. > <Implementation of other methods ofoff_Node. >