summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2011-08-16 12:40:36 -0500
committerNicholas E. Bofferding <bofferdn@us.ibm.com>2011-08-23 14:10:24 -0500
commit213b45cd7d8b0367f85ee68b79941f6d548c1e9c (patch)
tree8f78e3999420f6b1b2ca00ccb79f88cf54441d5c /src/usr
parent91b39e52483cc5a8cc1cb7c7d15c281a150d9572 (diff)
downloadtalos-hostboot-213b45cd7d8b0367f85ee68b79941f6d548c1e9c.tar.gz
talos-hostboot-213b45cd7d8b0367f85ee68b79941f6d548c1e9c.zip
Add target iterator and predicate support
Change-Id: I728bb312277591d81c0575e74878fba9f816b962 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/260 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/targeting/iterators/rangefilter.C89
-rw-r--r--src/usr/targeting/iterators/targetiterator.C88
-rw-r--r--src/usr/targeting/makefile21
-rw-r--r--src/usr/targeting/predicates/predicatebase.C54
-rw-r--r--src/usr/targeting/predicates/predicatectm.C63
-rw-r--r--src/usr/targeting/predicates/predicatepostfixexpr.C198
-rw-r--r--src/usr/targeting/targetservice.C108
-rw-r--r--src/usr/targeting/test/targetingtest.H533
-rw-r--r--src/usr/targeting/trace.H2
9 files changed, 1131 insertions, 25 deletions
diff --git a/src/usr/targeting/iterators/rangefilter.C b/src/usr/targeting/iterators/rangefilter.C
new file mode 100644
index 000000000..64ceb1f78
--- /dev/null
+++ b/src/usr/targeting/iterators/rangefilter.C
@@ -0,0 +1,89 @@
+
+/**
+ * @file rangefilter.C
+ *
+ * @brief Implementation of an object which takes an iterator range and
+ * allows caller to iterate through the elements which match a supplied
+ * predicate (filter)
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+
+// Targeting Component
+#include <targeting/iterators/rangefilter.H>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FUNC
+
+//******************************************************************************
+// Implementation
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+
+#define TARG_CLASS "RangeFilter<IteratorType>::"
+
+//******************************************************************************
+// RangeFilter<IteratorType>::advance
+//******************************************************************************
+
+template<typename IteratorType>
+void RangeFilter<IteratorType>::advance()
+{
+ if(iv_current != iv_end)
+ {
+ while( (++iv_current) != iv_end )
+ {
+ if( (!iv_pPredicate)
+ || ((*iv_pPredicate)(*iv_current)))
+ {
+ break;
+ }
+ }
+ }
+}
+
+//******************************************************************************
+// RangeFilter<IteratorType>::advanceIfNoMatch
+//******************************************************************************
+
+template<typename IteratorType>
+void RangeFilter<IteratorType>::advanceIfNoMatch()
+{
+ if( (iv_current != iv_end)
+ && ( (iv_pPredicate)
+ && (!((*iv_pPredicate)(*iv_current)))))
+ {
+ advance();
+ }
+}
+
+//******************************************************************************
+// Explicit template class member function instantiations
+//******************************************************************************
+
+template void RangeFilter<TargetIterator>::advance();
+template void RangeFilter<ConstTargetIterator>::advance();
+
+template void RangeFilter<TargetIterator>::advanceIfNoMatch();
+template void RangeFilter<ConstTargetIterator>::advanceIfNoMatch();
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
diff --git a/src/usr/targeting/iterators/targetiterator.C b/src/usr/targeting/iterators/targetiterator.C
new file mode 100644
index 000000000..f3549a633
--- /dev/null
+++ b/src/usr/targeting/iterators/targetiterator.C
@@ -0,0 +1,88 @@
+
+/**
+ * @file targetiterator.C
+ *
+ * @brief Implementation of iterator/const iterator used to iterate through
+ * target service targets
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+
+// Targeting Component
+#include <targeting/iterators/targetiterator.H>
+#include <targeting/targetservice.H>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FUNC
+
+//******************************************************************************
+// Implementation
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+
+#define TARG_CLASS "_TargetIterator<T>::"
+
+//******************************************************************************
+// TargetIterator::advance
+//******************************************************************************
+
+template<typename T>
+void _TargetIterator<T>::advance()
+{
+ TargetService& l_targetService = targetService();
+
+ // If cursor points to end()/NULL, do nothing. Otherwise, check to see if
+ // it should advance (possibly to NULL)
+ if(iv_pCurrent != NULL)
+ {
+ // Advance to end() if no targets available. Otherwise, check to see if
+ // it should advance (possibly to NULL)
+ if (l_targetService.iv_maxTargets > 0)
+ {
+ // If at or past last element, advance to end() else advance
+ if(iv_pCurrent >=
+ &(*l_targetService.iv_targets)[l_targetService.iv_maxTargets-1])
+ {
+ iv_pCurrent = NULL;
+ }
+ else
+ {
+ iv_pCurrent++;
+ }
+ }
+ else
+ {
+ iv_pCurrent = NULL;
+ }
+ }
+}
+
+//******************************************************************************
+// Explicit template class member function instantiations
+//******************************************************************************
+
+template void _TargetIterator<Target*>::advance();
+template void _TargetIterator<const Target*>::advance();
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
+
+
diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile
index 09b9d3be3..70edd18ac 100644
--- a/src/usr/targeting/makefile
+++ b/src/usr/targeting/makefile
@@ -1,7 +1,26 @@
ROOTPATH = ../../..
MODULE = targeting
-OBJS = target.o targetservice.o entitypath.o fakepnordata.o
+VPATH = \
+ predicates: \
+ iterators:
+
+PREDICATES_OBJS = \
+ predicatebase.o \
+ predicatepostfixexpr.o \
+ predicatectm.o
+
+ITERATORS_OBJS = \
+ targetiterator.o \
+ rangefilter.o
+
+TARGET_OBJS = \
+ target.o \
+ targetservice.o \
+ entitypath.o \
+ fakepnordata.o
+
+OBJS = ${TARGET_OBJS} ${PREDICATES_OBJS} ${ITERATORS_OBJS}
SUBDIRS = test.d
diff --git a/src/usr/targeting/predicates/predicatebase.C b/src/usr/targeting/predicates/predicatebase.C
new file mode 100644
index 000000000..61e17b984
--- /dev/null
+++ b/src/usr/targeting/predicates/predicatebase.C
@@ -0,0 +1,54 @@
+
+/**
+ * @file predicatebase.C
+ *
+ * @brief Implementation for an abstract targeting predicate which filters a
+ * set of targets based on the programmed criteria. Only required to
+ * implement the virtual destrutor which leads to duplicate weak symbols
+ * if it were instead inlined.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+
+// Targeting Component
+#include <targeting/predicates/predicatebase.H>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FN
+
+//******************************************************************************
+// Interface
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+#define TARG_CLASS "PredicateBase::"
+
+//******************************************************************************
+// PredicateBase::~PredicateBase
+//******************************************************************************
+
+PredicateBase::~PredicateBase()
+{
+ #define TARG_FN "~PredicateBase()"
+ #undef TARG_FN
+}
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
diff --git a/src/usr/targeting/predicates/predicatectm.C b/src/usr/targeting/predicates/predicatectm.C
new file mode 100644
index 000000000..8185020f5
--- /dev/null
+++ b/src/usr/targeting/predicates/predicatectm.C
@@ -0,0 +1,63 @@
+
+/**
+ * @file predicatectm.C
+ *
+ * @brief Implementation for a predicate which fiters a target based on its
+ * class, type, and model.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+
+// Targeting Component
+#include <targeting/target.H>
+#include <targeting/attributeenums.H>
+#include <targeting/predicates/predicatectm.H>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FN
+
+//******************************************************************************
+// Interface
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+#define TARG_CLASS "PredicateCTM::"
+
+//******************************************************************************
+// PredicateCTM::operator()
+//******************************************************************************
+
+bool PredicateCTM::operator()(
+ const Target* const i_pTarget) const
+{
+ #define TARG_FUNC "operator()(...)"
+
+ return ( ( (iv_class == CLASS_NA)
+ || (i_pTarget->getAttr<ATTR_CLASS>() == iv_class))
+ && ( (iv_type == TYPE_NA)
+ || (i_pTarget->getAttr<ATTR_TYPE>() == iv_type))
+ && ( (iv_model == MODEL_NA)
+ || (i_pTarget->getAttr<ATTR_MODEL>() == iv_model)));
+
+ #undef TARG_FUNC
+}
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
diff --git a/src/usr/targeting/predicates/predicatepostfixexpr.C b/src/usr/targeting/predicates/predicatepostfixexpr.C
new file mode 100644
index 000000000..7f5e89260
--- /dev/null
+++ b/src/usr/targeting/predicates/predicatepostfixexpr.C
@@ -0,0 +1,198 @@
+
+/**
+ * @file predicatepostfixexpr.C
+ *
+ * @brief Implementation for predicate which allows callers to chain multiple
+ * other predicates together in complex logical expressions, and then
+ * evaluate them against a target
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+
+// Other Host Boot Components
+#include <assert.h>
+
+// Targeting Component
+#include <targeting/predicates/predicatepostfixexpr.H>
+#include "../trace.H"
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+#undef TARG_NAMESPACE
+#undef TARG_CLASS
+#undef TARG_FN
+
+//******************************************************************************
+// Interface
+//******************************************************************************
+
+namespace TARGETING
+{
+
+#define TARG_NAMESPACE "TARGETING::"
+#define TARG_CLASS "PredicatePostfixExpr::"
+
+//******************************************************************************
+// PredicatePostfixExpr::PredicatePostfixExpr
+//******************************************************************************
+
+PredicatePostfixExpr::PredicatePostfixExpr()
+{
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::~PredicatePostfixExpr
+//******************************************************************************
+
+PredicatePostfixExpr::~PredicatePostfixExpr()
+{
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::push
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::push(
+ const PredicateBase* const i_pPredicate)
+{
+ #define TARG_FN "push(...)"
+
+ assert(i_pPredicate != NULL,
+ TARG_LOC "Caller supplied a NULL predicate");
+ Operation l_op = {EVAL,i_pPredicate};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::And
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::And()
+{
+ #define TARG_FN "And()"
+
+ Operation l_op = {AND,NULL};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::Not
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::Not()
+{
+ #define TARG_FN "Not()"
+
+ Operation l_op = {NOT,NULL};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::Or
+//******************************************************************************
+
+PredicatePostfixExpr& PredicatePostfixExpr::Or()
+{
+ #define TARG_FN "Or()"
+
+ Operation l_op = {OR,NULL};
+ iv_ops.push_back(l_op);
+ return *this;
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// PredicatePostfixExpr::operator()
+//******************************************************************************
+
+bool PredicatePostfixExpr::operator()(
+ const Target* const i_pTarget) const
+{
+ #define TARG_FN "operator()(...)"
+
+ assert(i_pTarget != NULL,
+ TARG_LOC "Caller supplied a NULL target");
+
+ std::vector<bool> l_stack;
+ bool l_result = false;
+
+ for(uint32_t i=0; i<iv_ops.size(); ++i)
+ {
+ switch(iv_ops[i].logicalOp)
+ {
+ case EVAL:
+ l_stack.push_back((*iv_ops[i].pPredicate)(i_pTarget));
+ break;
+ case AND:
+ assert(l_stack.size() >= 2,
+ TARG_LOC "Stack for AND must be >=2 but is %d",
+ l_stack.size());
+ l_result = l_stack.back();
+ l_stack.pop_back();
+ l_stack.back() &= l_result;
+ break;
+ case OR:
+ assert(l_stack.size() >= 2,
+ TARG_LOC "Stack for OR must be >= 2 but is %d",
+ l_stack.size());
+ l_result = l_stack.back();
+ l_stack.pop_back();
+ l_stack.back() |= l_result;
+ break;
+ case NOT:
+ assert(l_stack.size() >= 1,
+ TARG_LOC "Stack for NOT must be >= 1 but is %d",
+ l_stack.size());
+ l_stack.back() = !l_stack.back();
+ break;
+ default:
+ assert(0,
+ TARG_LOC "Attempted to evaluate unsupported "
+ "logical operation %d",
+ iv_ops[i].logicalOp);
+ break;
+ }
+ }
+
+ // If no predicates and we haven't asserted (no misformatting), element
+ // should be returned
+ if(l_stack.size() == 0)
+ {
+ l_result = true;
+ }
+ else
+ {
+ assert(l_stack.size() == 1,
+ TARG_LOC "Postfix expression created incorrectly. Stack "
+ "size should be 1 but is %d",
+ l_stack.size());
+
+ l_result = l_stack.front();
+ }
+
+ return l_result;
+
+ #undef TARG_FN
+}
+
+#undef TARG_CLASS
+#undef TARG_NAMESPACE
+
+} // End namespace TARGETING
+
diff --git a/src/usr/targeting/targetservice.C b/src/usr/targeting/targetservice.C
index 4418358ef..3b3b4098b 100644
--- a/src/usr/targeting/targetservice.C
+++ b/src/usr/targeting/targetservice.C
@@ -23,6 +23,7 @@
#include <targeting/targetservice.H>
#include "trace.H"
#include "fakepnordata.H"
+#include <targeting/predicates/predicatebase.H>
//******************************************************************************
// targetService
@@ -162,6 +163,72 @@ void TargetService::init()
}
//******************************************************************************
+// TargetService::begin (non-const version)
+//******************************************************************************
+
+TargetService::iterator TargetService::begin()
+{
+ #define TARG_FN "begin()"
+
+ assert(iv_initialized);
+
+ Target* l_pFirstTarget = (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0];
+
+ return iterator(l_pFirstTarget);
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// TargetService::begin (const version)
+//******************************************************************************
+
+//TargetService::const_iterator
+_TargetIterator<const Target*> TargetService::begin() const
+{
+ #define TARG_FN "begin() const"
+
+ assert(iv_initialized);
+
+ const Target* l_pFirstTarget =
+ (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0];
+
+ return const_iterator(l_pFirstTarget);
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// TargetService::end (non-const version)
+//******************************************************************************
+
+TargetService::iterator TargetService::end()
+{
+ #define TARG_FN "end()"
+
+ assert(iv_initialized);
+
+ return iterator(NULL);
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// TargetService::end (const version)
+//******************************************************************************
+
+TargetService::const_iterator TargetService::end() const
+{
+ #define TARG_FN "end() const"
+
+ assert(iv_initialized);
+
+ return const_iterator(NULL);
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
// TargetService::getTopLevelTarget
//******************************************************************************
@@ -305,10 +372,11 @@ bool TargetService::tryGetPath(
//******************************************************************************
void TargetService::getAssociated(
- const Target* const i_pTarget,
- const ASSOCIATION_TYPE i_type,
- const RECURSION_LEVEL i_recursionLevel,
- TargetHandleList& o_list) const
+ TargetHandleList& o_list,
+ const Target* const i_pTarget,
+ const ASSOCIATION_TYPE i_type,
+ const RECURSION_LEVEL i_recursionLevel,
+ const PredicateBase* const i_pPredicate) const
{
#define TARG_FN "getAssociated(...)"
@@ -340,13 +408,13 @@ void TargetService::getAssociated(
if (iv_associationMappings[i].associationDir == INWARDS)
{
(void) _getInwards(iv_associationMappings[i].attr,
- i_recursionLevel, l_entityPath, o_list);
+ i_recursionLevel, l_entityPath, i_pPredicate, o_list);
}
else if (iv_associationMappings[i].associationDir
== OUTWARDS)
{
(void) _getOutwards(iv_associationMappings[i].attr,
- i_recursionLevel, l_entityPath, o_list);
+ i_recursionLevel, l_entityPath, i_pPredicate, o_list);
}
else
{
@@ -509,10 +577,11 @@ uint32_t TargetService::_maxTargets()
//******************************************************************************
void TargetService::_getInwards(
- const ATTRIBUTE_ID i_attr,
- const RECURSION_LEVEL i_recursionLevel,
- EntityPath i_entityPath,
- TargetHandleList& o_list) const
+ const ATTRIBUTE_ID i_attr,
+ const RECURSION_LEVEL i_recursionLevel,
+ EntityPath i_entityPath,
+ const PredicateBase* const i_pPredicate,
+ TargetHandleList& o_list) const
{
#define TARG_FN "_getInwards(...)"
@@ -524,7 +593,10 @@ void TargetService::_getInwards(
EntityPath l_candidatePath;
bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i],
l_candidatePath);
- if (l_candidateFound && (l_candidatePath == i_entityPath))
+ if ( l_candidateFound
+ && (l_candidatePath == i_entityPath)
+ && ( (i_pPredicate == NULL)
+ || (*i_pPredicate)( &(*iv_targets)[i]) ) )
{
o_list.push_back(&(*iv_targets)[i]);
break;
@@ -545,10 +617,11 @@ void TargetService::_getInwards(
//******************************************************************************
void TargetService::_getOutwards(
- const ATTRIBUTE_ID i_attr,
- const RECURSION_LEVEL i_recursionLevel,
- EntityPath i_entityPath,
- TargetHandleList& o_list) const
+ const ATTRIBUTE_ID i_attr,
+ const RECURSION_LEVEL i_recursionLevel,
+ EntityPath i_entityPath,
+ const PredicateBase* const i_pPredicate,
+ TargetHandleList& o_list) const
{
#define TARG_FN "_getOutwards()...)"
@@ -573,7 +646,9 @@ void TargetService::_getOutwards(
|| ( (i_recursionLevel == ALL)
&& (l_candidatePath.size() > i_entityPath.size())))
{
- if (i_entityPath.equals(l_candidatePath,i_entityPath.size()))
+ if ( i_entityPath.equals(l_candidatePath,i_entityPath.size())
+ && ( (i_pPredicate == NULL)
+ || (*i_pPredicate)( &(*iv_targets)[i]) ) )
{
o_list.push_back(&(*iv_targets)[i]);
}
@@ -591,3 +666,4 @@ void TargetService::_getOutwards(
#undef TARG_NAMESPACE
} // End namespace TARGETING
+
diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H
index bd8ffdb0e..309bf3606 100644
--- a/src/usr/targeting/test/targetingtest.H
+++ b/src/usr/targeting/test/targetingtest.H
@@ -23,6 +23,9 @@
#include <targeting/entitypath.H>
#include <targeting/target.H>
#include <targeting/targetservice.H>
+#include <targeting/iterators/rangefilter.H>
+#include <targeting/predicates/predicatectm.H>
+#include <targeting/predicates/predicatepostfixexpr.H>
class TargetingTestSuite: public CxxTest::TestSuite
{
@@ -128,9 +131,11 @@ class TargetingTestSuite: public CxxTest::TestSuite
// TargetHandleList& o_list) const;
TargetHandleList l_list;
- (void) l_targetService.getAssociated(l_pTopLevel,
+ (void) l_targetService.getAssociated(
+ l_list,
+ l_pTopLevel,
TARGETING::TargetService::CHILD,
- TARGETING::TargetService::IMMEDIATE, l_list);
+ TARGETING::TargetService::IMMEDIATE);
if (!l_list.size())
{
TS_FAIL("Should have found some child elements" );
@@ -140,9 +145,11 @@ class TargetingTestSuite: public CxxTest::TestSuite
// target
TargetHandleList l_parentList;
- (void) l_targetService.getAssociated(l_list[0],
+ (void) l_targetService.getAssociated(
+ l_parentList,
+ l_list[0],
TARGETING::TargetService::PARENT,
- TARGETING::TargetService::IMMEDIATE, l_parentList);
+ TARGETING::TargetService::IMMEDIATE);
if (l_parentList.size() != 1)
{
@@ -155,18 +162,22 @@ class TargetingTestSuite: public CxxTest::TestSuite
"handle" );
}
- (void) l_targetService.getAssociated(l_pTopLevel,
+ (void) l_targetService.getAssociated(
+ l_list,
+ l_pTopLevel,
TARGETING::TargetService::CHILD_BY_AFFINITY,
- TARGETING::TargetService::IMMEDIATE, l_list);
+ TARGETING::TargetService::IMMEDIATE);
if (!l_list.size())
{
TS_FAIL("Should have found some child elements" );
}
- (void) l_targetService.getAssociated(l_pTopLevel,
+ (void) l_targetService.getAssociated(
+ l_list,
+ l_pTopLevel,
TARGETING::TargetService::CHILD_BY_AFFINITY,
- TARGETING::TargetService::ALL, l_list);
+ TARGETING::TargetService::ALL);
if (!l_list.size())
{
@@ -452,6 +463,512 @@ class TargetingTestSuite: public CxxTest::TestSuite
TS_TRACE(EXIT_MRK "testTargetClass" );
}
+
+ void testPredicateCtm()
+ {
+ TS_TRACE(ENTER_MRK "testPredicateCtm" );
+
+ using namespace TARGETING;
+ TargetService& l_targetService = targetService();
+
+ // Get top level (system) target
+ Target* l_pTopLevel = NULL;
+ (void) l_targetService.getTopLevelTarget(l_pTopLevel);
+ if (l_pTopLevel == NULL)
+ {
+ TS_FAIL("Top level handle was NULL when initialization "
+ "complete");
+ }
+
+ PredicateCTM l_allWild;
+ if( ! l_allWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM all wildcards filter should have matched system "
+ "target");
+ }
+
+ PredicateCTM l_typeModelWild(CLASS_SYS);
+ if( ! l_typeModelWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM class sys, remaining wildcards filter should have "
+ "matched system ");
+ }
+
+ PredicateCTM l_modelWild(CLASS_SYS,TYPE_SYS);
+ if( ! l_modelWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM class sys, type sys, remaining wildcards filter "
+ "should have matched system ");
+ }
+
+ PredicateCTM l_noWild(CLASS_SYS,TYPE_SYS,MODEL_POWER8);
+ if( ! l_noWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM class sys, type sys, model power8 should have "
+ "matched system ");
+ }
+
+ PredicateCTM l_classWild(CLASS_NA,TYPE_SYS,MODEL_POWER8);
+ if( ! l_classWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM class wild, type sys, model power8 should have "
+ "matched system ");
+ }
+
+ PredicateCTM l_typeWild(CLASS_SYS,TYPE_NA,MODEL_POWER8);
+ if( ! l_typeWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM class sys, wild, model power8 should have "
+ "matched system ");
+ }
+
+ PredicateCTM l_classModelWild(CLASS_NA,TYPE_SYS,MODEL_NA);
+ if( ! l_classModelWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM wild, type sys, wild should have "
+ "matched system ");
+ }
+
+ PredicateCTM l_classTypeWild(CLASS_NA,TYPE_NA,MODEL_NA);
+ if( ! l_classTypeWild(l_pTopLevel) )
+ {
+ TS_FAIL("CTM wild, wild, model should have "
+ "matched system ");
+ }
+
+ PredicateCTM l_chipClass(CLASS_CHIP,TYPE_NA,MODEL_NA);
+ if( l_chipClass(l_pTopLevel) )
+ {
+ TS_FAIL("CTM of class chip, wild, wild should not have matched "
+ "matched system ");
+ }
+
+ #if 0 // Prove copy CTOR/assignment operator is disabled
+ PredicateCTM l_ctmLhs;
+ PredicateCTM l_ctmRhs;
+
+ l_ctmLhs = l_ctmRhs;
+
+ PredicateCTM l_ctmCtor(l_ctmRhs);
+ #endif
+
+ PredicateBase* l_pBase = new PredicateCTM(CLASS_SYS);
+ delete l_pBase;
+ l_pBase = NULL;
+
+ TS_TRACE(EXIT_MRK "testPredicateCtm" );
+
+ }
+
+ void testPredicatePostfixExpr()
+ {
+ TS_TRACE(ENTER_MRK "testPredicatePostfixExpr" );
+
+ using namespace TARGETING;
+ TargetService& l_targetService = targetService();
+
+ // Get top level (system) target
+ Target* l_pTopLevel = NULL;
+ (void) l_targetService.getTopLevelTarget(l_pTopLevel);
+ if (l_pTopLevel == NULL)
+ {
+ TS_FAIL("Top level handle was NULL when initialization "
+ "complete");
+ }
+
+ PredicatePostfixExpr l_alwaysTrueExpr;
+ if(!l_alwaysTrueExpr(l_pTopLevel) )
+ {
+ TS_FAIL("Always true filter should have matched system");
+ }
+
+ #if 0
+ // Triggers NULL assertion check on push
+ l_alwaysTrueExpr.push(NULL);
+ #endif
+
+ #if 0
+ // Triggers not enough stack elements assertion when evaluating Not
+ l_alwaysTrueExpr.Not();
+ if(l_alwaysTrueExpr(l_pTopLevel) )
+ {
+ TS_FAIL("Negated always true filter should not have matched "
+ "system");
+ }
+ #endif
+
+ #if 0
+ // Triggers illegal target assertion
+ l_alwaysTrueExpr(NULL);
+ #endif
+
+ #if 0
+ // Triggers formatting assertion
+ l_alwaysTrueExpr.And();
+ l_alwaysTrueExpr(l_pTopLevel);
+ #endif
+
+ #if 0
+ // Triggers formatting assertion
+ l_alwaysTrueExpr.Or();
+ l_alwaysTrueExpr(l_pTopLevel);
+ #endif
+
+ PredicateCTM l_sysClass(CLASS_SYS);
+
+ #if 0
+ // Triggers formatting assertion
+ l_alwaysTrueExpr.push(&l_sysClass);
+ l_alwaysTrueExpr.And();
+ l_alwaysTrueExpr(l_pTopLevel);
+ #endif
+
+ #if 0
+ // Triggers formatting assertion
+ l_alwaysTrueExpr.push(&l_sysClass);
+ l_alwaysTrueExpr.Or();
+ l_alwaysTrueExpr(l_pTopLevel);
+ #endif
+
+ #if 0
+ // Triggers illegal formatting exception
+ // != 1 results on stack
+ l_alwaysTrueExpr.push(&l_sysClass);
+ l_alwaysTrueExpr.push(&l_sysClass);
+ l_alwaysTrueExpr.Not();
+ l_alwaysTrueExpr(l_pTopLevel);
+ #endif
+
+ PredicateCTM l_sysType(CLASS_NA,TYPE_SYS);
+ PredicateCTM l_power8Model(CLASS_NA,TYPE_NA,MODEL_POWER8);
+ PredicatePostfixExpr l_expr;
+ l_expr.push(&l_sysClass).push(&l_sysType).And();
+ l_expr.push(&l_power8Model).And();
+
+ if(!l_expr(l_pTopLevel) )
+ {
+ TS_FAIL("CTM of class sys && type sys && model power8 should "
+ "have matched system");
+ }
+
+ l_expr.Not();
+
+ if(l_expr(l_pTopLevel) )
+ {
+ TS_FAIL("CTM of class sys && type sys && model power8 should "
+ "npt have matched system after negation");
+ }
+
+ l_expr.push(&l_sysClass);
+ l_expr.Or();
+
+ if(!l_expr(l_pTopLevel) )
+ {
+ TS_FAIL("CTM of class sys && type sys && model power8 should "
+ "have matched system after negation then || sys class");
+ }
+
+ PredicatePostfixExpr* l_pExpr = new PredicatePostfixExpr;
+ l_pExpr->push(&l_sysClass).push(&l_sysType).And();
+ l_pExpr->push(&l_power8Model).And();
+ delete (static_cast<PredicateBase*>(l_pExpr));
+
+ #if 0
+ PredicatePostfixExpr l_lhs;
+ PredicatePostfixExpr l_rhs;
+
+ l_lhs = l_rhs;
+
+ PredicatePostfixExpr l_cpCtor(l_rhs);
+ #endif
+
+
+ TS_TRACE(EXIT_MRK "testPredicatePostfixExpr" );
+ }
+
+ void testTargetIterator()
+ {
+ TS_TRACE(ENTER_MRK "testTargetIterator");
+
+ using namespace TARGETING;
+ TargetService& l_targetService = targetService();
+
+
+ TargetIterator l_pIt;
+ if( l_pIt != l_targetService.end() )
+ {
+ TS_FAIL("Default TargetIterator should point to past the end "
+ "of container");
+ }
+
+ ++l_pIt;
+ if( l_pIt != l_targetService.end() )
+ {
+ TS_FAIL("Default TargetIterator preincremented should point to "
+ "past the end of container");
+ }
+
+ TargetIterator* l_pItNew = new TargetIterator;
+ delete l_pItNew;
+ l_pItNew = NULL;
+
+ if(*l_pIt != NULL)
+ {
+ TS_FAIL("Default TargetIterator dereference should return NULL");
+ }
+
+ // Get top level (system) target to verify at least 1 target
+ Target* l_pTopLevel = NULL;
+ (void) l_targetService.getTopLevelTarget(l_pTopLevel);
+ if (l_pTopLevel == NULL)
+ {
+ TS_FAIL("Top level handle was NULL when initialization "
+ "complete");
+ }
+
+ l_pIt = l_targetService.begin();
+ if((*l_pIt) == NULL)
+ {
+ TS_FAIL("TargetService begin() should return !NULL");
+ }
+
+ CLASS l_class = CLASS_NA;
+ if( !l_pIt->tryGetAttr<ATTR_CLASS>(l_class) )
+ {
+ TS_FAIL("Failed to get expected class attribute");
+ }
+
+ TargetIterator l_rhs = l_targetService.begin();
+ if( ! (l_pIt == l_rhs) )
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ l_rhs = l_targetService.begin();
+ if( l_pIt != l_rhs )
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ TargetIterator l_rhs2 = l_targetService.begin();
+ ++l_rhs2;
+ ++l_pIt;
+ if( l_pIt != l_rhs2 )
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ l_rhs2++;
+ l_pIt++;
+ if( l_pIt != l_rhs2 )
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ TargetIterator l_pItClone(l_rhs2);
+ if( l_pIt != l_pItClone)
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ if(l_pIt != l_pItClone++)
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ if( (++l_pIt) != l_pItClone)
+ {
+ TS_FAIL("Iterators should be equal, but aren't");
+ }
+
+ const TargetService& l_constTargetService = targetService();
+
+ ConstTargetIterator l_pConstIt;
+ if( l_pConstIt != l_constTargetService.end() )
+ {
+ TS_FAIL("Default ConstTargetIterator should point to past the "
+ "end of container");
+ }
+
+ l_pConstIt = l_constTargetService.begin();
+ if( (*l_pConstIt) == NULL)
+ {
+ TS_FAIL("Iterator does not point to valid Target as expected");
+ }
+
+ TS_TRACE(EXIT_MRK "testTargetIterator" );
+ }
+
+ void testRangeFilter(void)
+ {
+ TS_TRACE(ENTER_MRK "testRangeFilters" );
+
+ using namespace TARGETING;
+
+ TargetRangeFilter* l_pRangeFilter = new TargetRangeFilter(
+ targetService().begin(),
+ targetService().end(),
+ NULL);
+ delete l_pRangeFilter;
+ l_pRangeFilter = NULL;
+
+
+ TargetRangeFilter l_f1(
+ targetService().begin(),
+ targetService().end(),
+ NULL);
+
+ Target* l_pBegin = (*l_f1);
+ ++l_f1;
+ Target* l_pNext = (*l_f1);
+ if( (l_pBegin == NULL)
+ || (l_pNext == NULL)
+ || (l_pBegin == l_pNext)
+ )
+ {
+ TS_FAIL("Target* pointed to by Begin/next NULL -or- begin =="
+ "next");
+ }
+
+ l_f1.reset();
+ if( *l_f1 != l_pBegin )
+ {
+ TS_FAIL("Target* after reset should be equal to original");
+ }
+
+ l_f1.reset();
+ TargetRangeFilter l_f2 = l_f1;
+ PredicateCTM l_ctm(CLASS_SYS,TYPE_CORE); // Nonsense CTM
+ l_f1.setPredicate(&l_ctm);
+ if( *l_f1 == l_pBegin )
+ {
+ TS_FAIL("Target* after reset and change of predicate should be"
+ "different than the original");
+ }
+
+ PredicateCTM l_ctm1(CLASS_CHIP,TYPE_PROC);
+
+ TargetRangeFilter l_f3(
+ targetService().begin(),
+ targetService().end(),
+ &l_ctm1);
+ for(;l_f3;++l_f3)
+ {
+ if(l_f3->getAttr<ATTR_TYPE>() != TYPE_PROC)
+ {
+ TS_FAIL("Should only have returned type proc");
+ break;
+ }
+ }
+
+ TargetIterator l_pIt = targetService().begin();
+ ++l_pIt;
+ ++l_pIt;
+
+ if(l_pIt == targetService().end())
+ {
+ TS_FAIL("Not enough elements for test");
+ }
+
+ TargetRangeFilter l_partial(
+ targetService().begin(),
+ l_pIt,
+ NULL);
+ int i=0;
+
+ for(; l_partial; ++l_partial)
+ {
+ i++;
+ }
+
+ if(i != 2)
+ {
+ TS_FAIL("Should have gotten 2 elements %d",i);
+ }
+
+ TS_TRACE(EXIT_MRK "testRangeFilter" );
+ }
+
+ void testComplexFilter(void)
+ {
+ TS_TRACE(ENTER_MRK "testComplexFilter" );
+
+ using namespace TARGETING;
+
+ TargetService& l_targetService = targetService();
+
+ TargetRangeFilter f(l_targetService.begin(),
+ l_targetService.end(),
+ NULL);
+ int l_count = 0;
+ for(; f; ++f, l_count++)
+ {
+ }
+
+ TS_TRACE(INF_MRK "Found %d total targets", l_count);
+
+ PredicateCTM l_procs(CLASS_CHIP);
+ PredicateCTM l_enclosures(CLASS_ENC);
+ PredicatePostfixExpr l_query;
+ l_query.push(&l_procs).push(&l_enclosures).Or();
+
+ f.setPredicate(&l_query);
+ f.reset();
+
+ l_count = 0;
+ for(; f; ++f, ++l_count)
+ {
+ EntityPath l_path = f->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+ }
+
+ TS_TRACE(INF_MRK "Found %d targets that are chips or enclosures ",
+ l_count);
+
+ l_query.Not();
+ f.reset();
+
+ l_count = 0;
+ for(; f; ++f, ++l_count)
+ {
+ }
+
+ TS_TRACE(INF_MRK "Found %d targets that are not chips or "
+ "enclosures",l_count);
+
+ Target* l_pMasterProcChipTargetHandle = NULL;
+ (void) l_targetService.masterProcChipTargetHandle(
+ l_pMasterProcChipTargetHandle);
+ if(l_pMasterProcChipTargetHandle == NULL)
+ {
+ TS_FAIL("Master processor chip target not found");
+ }
+
+ PredicateCTM l_ex(CLASS_UNIT,TYPE_EX);
+ PredicateCTM l_mba(CLASS_UNIT,TYPE_MBA);
+ PredicatePostfixExpr l_procquery;
+ l_procquery.push(&l_ex).push(&l_mba).Or();
+
+ TargetHandleList l_list;
+ (void) targetService().getAssociated(
+ l_list,
+ l_pMasterProcChipTargetHandle,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL,
+ &l_procquery);
+
+ l_count = 0;
+ for(uint32_t i=0; i<l_list.size(); ++i, ++l_count)
+ {
+ EntityPath l_path = l_list[i]->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+ }
+
+ TS_TRACE(INF_MRK "Found %d targets that are ex/mba units off "
+ "master processor",l_count);
+
+ TS_TRACE(EXIT_MRK "testComplexFilter" );
+ }
};
#endif // End __TESTTARGETING_H
diff --git a/src/usr/targeting/trace.H b/src/usr/targeting/trace.H
index d16ef8ece..e7ffe0365 100644
--- a/src/usr/targeting/trace.H
+++ b/src/usr/targeting/trace.H
@@ -22,6 +22,8 @@ namespace TARGETING
extern trace_desc_t* g_trac_targeting;
}
+#define TARG_LOC TARG_NAMESPACE TARG_CLASS TARG_FN ": "
+
#define TARG_TAG "[TARG]"
#define TARG_ENTER(args...) \
TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " ENTER_MRK " " TARG_NAMESPACE \
OpenPOWER on IntegriCloud