Off used two kinds of identifiers:
off_id_t composed by
creation_node:sequence_number:implementor_index and used for
mobile objects (including resource containers and abstract
resources),
\item and off_eu_id_t composed by off_id_t:name-used-in-hw for
the elementary hardware units being exported.
Off++ uses just one kind. When the name-used-in-hw is zero such a
name can be considered to be an Off's off_id_t.
The size of each identifier field is defined as shown.
<Off identifier fields data types. >= (U->) // Fields for system identifiers. typedef unsigned32_t off_node_t; // Node descriptor typedef unsigned32_t off_seq_t; // Sequence number typedef unsigned32_t off_slot_t; // Slot number typedef off_mdep_offset_t off_offset_t;// Elementary unit offset number
Definesoff_node_t,off_offset_t,off_seq_t,off_slot_t(links are to index).
Null constant are provided for every field.
<Off identifier field null values. >= (U->) const off_node_t OFF_ND_NULL = (off_node_t)0; const off_seq_t OFF_SEQ_NULL = (off_seq_t)0; const off_slot_t OFF_SLOT_NULL = (off_slot_t)0; const off_offset_t OFF_OFFSET_NULL= (off_offset_t)0;
DefinesOFF_ND_NULL,OFF_OFFSET_NULL,OFF_SEQ_NULL,OFF_SLOT_NULL(links are to index).
<Off identifier dependencies. >= (U->) [D->] #include <flux/types.h> // for boolean_t natural_t et al.
Note that the offset is a machine dependent value, because it usually correspond to the physical resource name which turns out to fit in a machine register.
Thus, identifiers are typed:
<Off identifiers. >= (U->)
// Relocatable top level identifier
//
typedef
struct off_id_t {
off_node_t i_node : 32; // Creation node for the object
off_seq_t i_seq : 32; // Sequence number
off_slot_t i_slot : 32; // Implementor descriptor for the object
off_offset_t i_offset; // Object id relative to the container.
<Other public members of off_id_t. >
};
// elementary unit identifier
//
typedef off_id_t off_eu_id_t;
Definesoff_eu_id_t,off_id_t(links are to index).
<Off identifier dependencies. >+= (U->) [<-D->] #include <klib/mdep/ids.h> // for off_mdep_offset_t
Identifier equality must not take into account just the slot
member of the identifier.
<Other public members of off_id_t. >= (<-U) [D->]
int operator==(const off_id_t &other) const {
return (i_offset == other.i_offset &&
i_seq == other.i_seq &&
i_node== other.i_node );
}
int operator!=(const off_id_t &other) const {
return (i_offset != other.i_offset ||
i_seq != other.i_seq ||
i_node!= other.i_node );
}
An elementary unit identifier can be declared uninitialized and also constructed with a pre-specified value.
<Other public members of off_id_t. >+= (<-U) [<-D->]
off_id_t(void){;}
off_id_t(off_node_t nd, off_seq_t seq, off_slot_t slot, off_offset_t offset):
i_node(nd),i_seq(seq),i_slot(slot),i_offset(offset)
{;}
off_id_t(const off_id_t &p, const off_offset_t o)
{ *this=p; i_offset=o; }
Besides, some arithmetic can be done on identifiers
<Other public members of off_id_t. >+= (<-U) [<-D->]
const off_id_t operator+(const int i) const {
return off_id_t(*this,i_offset+i);
}
const off_id_t operator-(const int i) const {
return off_id_t(*this,i_offset-i);
}
off_id_t &operator++(void) { i_offset++; return *this; }
off_id_t &operator--(void) { i_offset--; return *this; }
off_id_t operator++(int i) {
off_id_t r=*this; i_offset+=i; return r;
}
off_id_t operator--(int i) {
off_id_t r=*this; i_offset+=i; return r;
}
const off_id_t &operator+=(const int i) { i_offset+=i; return *this; }
const off_id_t &operator-=(const int i) { i_offset-=i; return *this; }
int operator-(const off_id_t &u) const { return i_offset-u.i_offset; }
Finally, an elementary unit can also be understood as a (local) machine dependent name.
<Other public members of off_id_t. >+= (<-U) [<-D]
operator off_offset_t(void) const { return i_offset; }
There are some synonyms defined mostly for documentation purposes. They correspond to system objects that we will be seeing below.
<Off identifier synonyms. >= (U->) // Some synonyms for common system object identifiers. typedef off_id_t off_shtl_id_t; // Shuttle identifier. typedef off_id_t off_prtl_id_t; // Portal identifier. typedef off_id_t off_dtlb_id_t; // DTLB identifer. typedef off_id_t off_proc_id_t; // Processor id. typedef off_eu_id_t off_pg_id_t; // Page frame id. typedef off_eu_id_t off_io_id_t; // IO port id. typedef off_eu_id_t off_ev_id_t; // HW Event id. typedef off_eu_id_t off_tmr_id_t; // HW timer id. typedef off_eu_id_t off_dma_id_t; // DMA line id. typedef off_eu_id_t off_ts_id_t; // Processor time slice.
Definesoff_dma_id_t,off_dtlb_id_t,off_eu_id_t,off_io_id_t,off_pg_id_t,off_proc_id_t,off_prtl_id_t,off_shtl_id_t,off_tmr_id_t,off_ts_id_t(links are to index).
Null values are also available.
<Off identifer null values. >= (U->) const off_id_t OFF_ID_NULL(0,0,0,0); const off_id_t OFF_SHTL_NULL=OFF_ID_NULL; const off_id_t OFF_PRTL_NULL=OFF_ID_NULL; const off_id_t OFF_DTLB_NULL=OFF_ID_NULL; const off_eu_id_t OFF_EU_ID_NULL=OFF_ID_NULL;
DefinesOFF_DTLB_NULL,OFF_EU_ID_NULL,OFF_ID_NULL,OFF_PRTL_NULL,OFF_SHTL_NULL(links are to index).
Finally, an operator is provided to print system identifiers.
<Off identifiers operator<<. >= (U->)
// Dumps an ID.
OStr &operator<<(OStr &s, const off_id_t &i);
<Off identifier dependencies. >+= (U->) [<-D] #include <klib/str.h> // for OStr
There implementation is simple.
<Off identifiers operator<< implementation. >= (U->)
// Dumps an ID.
OStr &operator<<(OStr &s, const off_id_t &i)
{
s << fmt("%04x",i.i_node) <<
":" << fmt("%08x",i.i_seq) <<
":" << fmt("%04x",i.i_slot) << "::" << fmt("%08x",i.i_offset);
return s;
}
\subsubsection{Identifiers \cpp{} source files}
Identifier code can be found in klib/ids.h and klib/ids.C.
<ids.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_IDS_H
#define __OFF_IDS_H 1
<Off identifier dependencies. >
<Off identifier fields data types. >
<Off identifiers. >
<Off identifier synonyms. >
<Off identifier field null values. >
<Off identifer null values. >
<Off identifiers operator<<. >
#endif // __OFF_IDS_H
<ids.C*>=
<Read the literate code instead warning. >
#include <klib/ids.h> // Exported interface.
<Off identifiers operator<< implementation. >
\subsubsection{Machine dependent identifiers}
We must define off_mdep_offset_t to match the largest physical
resource name. This definition is kept in klib/mdep/ids.h.
<mdep ids.h*>= #ifndef __OFF_MDEP_IDS_H #define __OFF_MDEP_IDS_H 1 #include <flux/types.h> // for unsigned32_t typedef unsigned32_t off_mdep_offset_t; #endif // __OFF_MDEP_IDS_H