From: <ro...@us...> - 2012-08-17 17:32:30
|
Revision: 2793 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2793&view=rev Author: ron-fox Date: 2012-08-17 17:32:22 +0000 (Fri, 17 Aug 2012) Log Message: ----------- Development of Feature #1161 functionality. Modified Paths: -------------- branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.cpp branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.h branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.am branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.in branches/nscldaq-10.2-development/daq/eventbuilder/OrdererPackage.cpp branches/nscldaq-10.2-development/daq/eventbuilder/eventOrderer.tcl Added Paths: ----------- branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.cpp branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.h Modified: branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.cpp =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.cpp 2012-08-16 16:07:27 UTC (rev 2792) +++ branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.cpp 2012-08-17 17:32:22 UTC (rev 2793) @@ -45,8 +45,7 @@ */ CFragmentHandler::CFragmentHandler() : m_nOldest(UINT64_MAX), - m_nNewest(0), - m_nCoincidenceWindow(0) // Exact matching required. + m_nNewest(0) { m_nBuildWindow = DefaultBuildWindow; m_pInstance = this; @@ -117,17 +116,19 @@ pFragments = reinterpret_cast<EVB::pFlatFragment>(pNext); } /** - * A bit of subtlety here: - * The builds are done in batches if possible (hence the window*2). - * We want to be sure that no events overhang the the build window - * hence the addition of the coincidence window to the stuff that - * figures out when to stop. + ** Using 2* the build window above forces + ** the builds to be batched which hopefully run the output stages + ** more efficiently: */ if ((m_nNewest - m_nOldest) > m_nBuildWindow*2) { - while (!(queuesEmpty() && - (m_nNewest - m_nOldest) > (m_nBuildWindow + m_nCoincidenceWindow))) { - buildEvent(); + std::vector<EVB::pFragment> sortedFragments; + while (!(queuesEmpty()) && + ((m_nNewest - m_nOldest) > m_nBuildWindow)) { + + sortedFragments.push_back(popOldest()); + } + observe(sortedFragments); } } /** @@ -143,20 +144,8 @@ { m_nBuildWindow = windowWidth; } + /** - * setConicidenceWindow - * - * Set the maximum number of ticks fragments can differ by and still live in - * the same event.. - * - * @param timeDifference - The new coincidence window width. - */ -void -CFragmentHandler::setCoincidenceWindow(uint64_t timeDifference) -{ - m_nCoincidenceWindow = timeDifference; -} -/** * addObserver * * The fragment handler does not really know how to deal with built @@ -203,52 +192,109 @@ void CFragmentHandler::flush() { + std::vector<EVB::pFragment> fragments; while(!queuesEmpty()) { - buildEvent(); + fragments.push_back(popOldest()); } + observe(fragments); + // reset newest/oldest to initial m_nNewest = 0; m_nOldest = UINT64_MAX; } -/*-------------------------------------------------------------------] - ** Utility methods (private). - */ - /** - * Build an event. An event is built as a gather vector of - * pointers to event fragments that have been removed from - * their fragment queues: - * - all fragments in all queues whose time is different from - * m_nOldest by less than m_nCoincidence window are put in the event. - * - A running new 'oldest' is computed. - * - observe() is run to invoke the observers. - * - The fragments are freed. - * - life goes on ;-) + * getStatistics + * + * Return information about the fragment statistics. + * This can be used to drive a GUI that monitors the status + * of the software. + * + * @return CFragmentHandler::InputStatistics + * @retval struct that has the following key fields: + * - s_oldestFragment - The timestamp of the oldest queued fragment. + * - s_newestFragment - The timestamp of the newest queued fragment. + * - s_totalQueuedFragments - Total number of queued fragments. + * - s_queueStats - vector of individual queue statistics. + * each element is a struct of type + * CFragmentHandler::QueueStatistics which has the fields: + * # s_queueId - Source id of the queue. + * # s_queueDepth - number of fragments in the queue. + * # s_oldestElement - Timestamp at head of queue. */ -void -CFragmentHandler::buildEvent() +CFragmentHandler::InputStatistics +CFragmentHandler::getStatistics() { - Builder b(m_nCoincidenceWindow, m_nOldest); - Builder& bref(b); + InputStatistics result; - // Let the builder build up the event and adjust the + // get the individual chunks: - for_each(m_FragmentQueues.begin(), m_FragmentQueues.end(), bref); + result.s_oldestFragment = m_nOldest; + result.s_newestFragment = m_nNewest; - std::vector<EVB::pFragment>& event(b.getEvent()); - observe(event); + QueueStatGetter statGetter; + QueueStatGetter& rstatGetter(statGetter); - // Kill off the fragments: + for_each(m_FragmentQueues.begin(), m_FragmentQueues.end(), rstatGetter); - for_each(event.begin(), event.end(), freeFragment); + result.s_totalQueuedFragments = statGetter.totalFragments(); + result.s_queueStats = statGetter.queueStats(); - // Update the oldest event (building does not change newest). - m_nOldest = b.getOldest(); + return result; +} +/*-------------------------------------------------------------------] + ** Utility methods (private). + */ +/** + * popOldest + * + * Remove an oldest fragment from the sources queue and update m_nOldest + * + * @return ::EVB::pFragment - pointer to a fragment whose timestamp + * matches m_nOldest + * + * @note this is all very brute force. A much quicker algorithm to find + * the oldest fragment would be to retain in addtion to m_nOldest + * the queue that it was put in...however we still need to iterate + * over the queues to update m_nOldest. This is a bit + * short circuited by: + * - Keeping track of it as we search for the first match to m_nOldest + * - short circuiting the loop if we find another queue with + * an m_nOldest match as there can't be anything older than that + * by definition. + */ +::EVB::pFragment +CFragmentHandler::popOldest() +{ + uint64_t nextOldest = m_nNewest; // Must be older than that. + ::EVB::pFragment pOldest(0); + for(Sources::iterator p = m_FragmentQueues.begin(); + p != m_FragmentQueues.end(); p++) { + ::EVB::pFragment pFrag = p->second.front(); + uint64_t stamp = pFrag->s_header.s_timestamp; + if(!pOldest && (stamp == m_nOldest)) { + + // This is the one. + + pOldest = pFrag; + p->second.pop(); + } + // Get pFrag again in case the test above worked. + // update nextOldest and break if it matches m_nOldest. + + pFrag = p->second.front(); + stamp = pFrag->s_header.s_timestamp; + if (stamp < nextOldest) nextOldest = stamp; + if (nextOldest == m_nOldest) break; + + } + m_nOldest = nextOldest; + return pOldest; } + /** * observe * @@ -265,6 +311,11 @@ (*pObserver)(event); p++; } + // Delete the fragments in the vector as we're done with them now: + + for(int i =0; i < event.size(); i++) { + freeFragment(event[i]); + } } /** * addFragment @@ -340,82 +391,59 @@ return true; } /*----------------------------------------------------------- - ** Locally defnie classers + ** Locally defined classers */ - /** - * @class CFragmentHandler::Builder + * @class QueueStateGetter * - * A visitor of each element of the Sources map. - * This builds up an event with each visitation by pulling - * off queue elements that are within a coincidence interval. - * The oldest fragment not added to the event is also built up - * during the iteration. + * Event source queue visitor that gathers input statistics. + * This class is a functional and is intended to be called from + * a for_each loop over the set of input queues. + * It gathers the total number of fragments as well + * as the number of fragments in the queue and the oldest fragment in the queue. */ /** - * Builder + * operator() + * Called for each queue to accumulate stats for that queue. * - * Constructor: - * - Save the coincidence interval. - * - Set the oldest stamp to UINT64_MAX. - * - * @param interval - Build coincidence interval. - * @param oldest - The oldest fragment in all queues. + * @param source - reference to that data source queue. */ -CFragmentHandler::Builder::Builder(uint64_t interval, uint64_t oldest) : - m_nOldestNotBuilt(UINT64_MAX), - m_nOldestCurrent(oldest), - m_nCoincidenceInterval(interval) -{} - -/** - * operator() - * - * Function call operator. This is called for each node - * of the Sources map. It removes all queue elements - * that are within m_nCoincidenceInterval from the queue - * and adds them to the event that is being built up. - * If necesary, m_nOldestNotBuilt is updated. - * - * @param source - reference to the map source element (a pair). - */ void -CFragmentHandler::Builder::operator()(CFragmentHandler::SourceElementV& source) +CFragmentHandler::QueueStatGetter::operator()(SourceElementV& source) { - uint64_t latestAllowed = m_nOldestCurrent + m_nCoincidenceInterval; - SourceQueue& q(source.second); + SourceQueue& sourceQ(source.second); - while ((!q.empty()) && (q.front()->s_header.s_timestamp < latestAllowed)) { - m_Event.push_back(q.front()); - q.pop(); - - } - // Update oldest if necessary: + QueueStatistics stats; + stats.s_queueId = source.first; + stats.s_queueDepth = sourceQ.size(); + stats.s_oldestElement = sourceQ.front()->s_header.s_timestamp; - if (!q.empty() && (q.front()->s_header.s_timestamp < m_nOldestNotBuilt)) { - m_nOldestNotBuilt = q.front()->s_header.s_timestamp; - - } + m_nTotalFragments += stats.s_queueDepth; + m_Stats.push_back(stats); } /** - * getEvent - * Return a reference to the built event: + * totalFragments() + * + * Return the total number of queued elements. * - * @return std::vector<pFragment>& + * @return uint32_t */ -std::vector<EVB::pFragment>& -CFragmentHandler::Builder::getEvent() +uint32_t +CFragmentHandler::QueueStatGetter::totalFragments() { - return m_Event; + return m_nTotalFragments; } /** - * Get the new oldest timestamp. + * queueStats * - * @return uint64_t + * Return the queue statistics vector: + * + * @return std::vector<QueueStatistics> + * */ -uint64_t -CFragmentHandler::Builder::getOldest() const +std::vector<CFragmentHandler::QueueStatistics> +CFragmentHandler::QueueStatGetter::queueStats() { - return m_nOldestNotBuilt; + return m_Stats; } Modified: branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.h =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.h 2012-08-16 16:07:27 UTC (rev 2792) +++ branches/nscldaq-10.2-development/daq/eventbuilder/CFragmentHandler.h 2012-08-17 17:32:22 UTC (rev 2793) @@ -87,39 +87,55 @@ class CFragmentHandler { private: + // Private data types: + typedef std::queue<EVB::pFragment> SourceQueue, *pSourceQueue; typedef std::map<uint32_t, SourceQueue> Sources, *pSources; typedef std::pair<uint32_t, SourceQueue> SourceElement, *pSourceElement; typedef std::pair<const uint32_t, SourceQueue> SourceElementV; - + + // public data types: public: + typedef struct _QueueStatistics { + uint32_t s_queueId; + uint32_t s_queueDepth; + uint64_t s_oldestElement; + } QueueStatistics, *pQueueStatistics; + + typedef struct _InputStatistics { + uint64_t s_oldestFragment; + uint64_t s_newestFragment; + uint32_t s_totalQueuedFragments; + + std::vector<QueueStatistics> s_queueStats; + } InputStatistics, *pInputStatistics; + +public: // Observer base class: class Observer { public: virtual ~Observer() {} // So we can chain destructors. + + + public: virtual void operator()(const std::vector<EVB::pFragment>& event) = 0; // Passed built event gather maps. }; - - // Build observer: + // Queue statistics accumulator: + private: + class QueueStatGetter { + private: + uint32_t m_nTotalFragments; + std::vector<QueueStatistics> m_Stats; + public: + void operator()(SourceElementV& source); + uint32_t totalFragments(); + std::vector<QueueStatistics> queueStats(); + }; - class Builder { - private: - std::vector<EVB::pFragment> m_Event; - uint64_t m_nOldestNotBuilt; - uint64_t m_nOldestCurrent; - uint64_t m_nCoincidenceInterval; - - public: - Builder(uint64_t interval, uint64_t oldest); - void operator()(SourceElementV& source); - std::vector<EVB::pFragment>& getEvent(); - uint64_t getOldest() const; - }; - private: @@ -127,12 +143,8 @@ private: uint64_t m_nOldest; //< Oldest fragment seen in terms of ticks. uint64_t m_nNewest; //< Newest fragment seen in terms of ticks. - uint64_t m_nBuildWindow; - uint64_t m_nCoincidenceWindow; - std::list<Observer*> m_Observers; - Sources m_FragmentQueues; @@ -140,7 +152,8 @@ - // Canonicals/creationals. Note that since this is a singleton, construction is private. + // Canonicals/creationals. Note that since this is a singleton, construction + // is private. private: CFragmentHandler(); @@ -156,7 +169,7 @@ // The only public creational is getInstance: public: - CFragmentHandler* getInstance(); + static CFragmentHandler* getInstance(); // here are the operations we advertised: @@ -164,18 +177,20 @@ void addFragments(size_t nSize, EVB::pFlatFragment pFragments); void setBuildWindow(uint64_t windowWidth); - void setCoincidenceWindow(uint64_t timeDifference); void addObserver(Observer* pObserver); void removeObserver(Observer* pObserver); void flush(); + + // Get state of the queues etc. + InputStatistics getStatistics(); // utility methods: private: - void buildEvent(); + ::EVB::pFragment popOldest(); void observe(const std::vector<EVB::pFragment>& event); // pass built events on down the line. void addFragment(EVB::pFlatFragment pFragment); size_t totalFragmentSize(EVB::pFragmentHeader pHeader); Added: branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.cpp =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.cpp (rev 0) +++ branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.cpp 2012-08-17 17:32:22 UTC (rev 2793) @@ -0,0 +1,126 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2009. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include "CInputStatsCommand.h" +#include "CFragmentHandler.h" + +#include <TCLInterpreter.h> +#include <TCLObject.h> +#include <tcl.h> + +/*------------------------------------------------------------------- +** Canonicals: +*/ + +/** + * CInputStatsCommand + * + * Constructor; registers the object as a command processor + * on an interpreter. + * + * @param interp - Interpreter on which we're registering. + * @param command - Command name (e.g. ::EVB::inputStats). + */ +CInputStatsCommand::CInputStatsCommand(CTCLInterpreter& interp, std::string command) : + CTCLObjectProcessor(interp, command, false) +{} + +/** + * ~CInputStatsCommand + * + * Destructor: the base class constructor takes care of unregistration. + */ +CInputStatsCommand::~CInputStatsCommand() +{} + +/*------------------------------------------------------------------ +** Virtual method overrides. +*/ + +/** + * operator() + * + * This method is called by the Tcl interpreter when the command is + * invoked. + * + * @param interp - Reference to the interpreter that is executing the command. + * @param objv - Reference to the vector of command line words. + * + * @return int - Status of the command: + * @retval TCL_OK - success. + * @return TCL_ERROR - failure. The only possible failure is that there are too + * many command objects. + * @note See the class description for information about the result returned by this + * command. On error, an error message is set as the result. + */ +int +CInputStatsCommand::operator()(CTCLInterpreter& interp, std::vector<CTCLObject>& objv) +{ + if (objv.size() != 1) { + std::string error="Too many command line parameters"; + interp.setResult(error); + return TCL_ERROR; + } + // Get the fragment handler and statistics strruct: + + CFragmentHandler* pQueues = CFragmentHandler::getInstance(); + CFragmentHandler::InputStatistics stats = pQueues->getStatistics(); + + /* + Marshall the data into a result object and set it as the result. + we use objects because it's easier to build the lists/nestsed lists that way. + Note that tcl.h assures us that Tcl_WideInt is at least 64 bits wide. + */ + CTCLObject result; + + result.Bind(interp); + + // Timestamps get added as WidInt objs? + + CTCLObject wideInt; + wideInt.Bind(interp); + + wideInt = (Tcl_WideInt)(stats.s_oldestFragment); + result += wideInt; + + wideInt = (Tcl_WideInt)(stats.s_newestFragment); + result += wideInt; + + result += (int)(stats.s_totalQueuedFragments); + + // Now the individual queue stats as a list of lists: + + CTCLObject QueueStatList; + QueueStatList.Bind(interp); + + + for (int i = 0; i < stats.s_queueStats.size(); i++) { + CTCLObject aQueueStat; + aQueueStat.Bind(interp); + + aQueueStat += (int)stats.s_queueStats[i].s_queueId; + aQueueStat += (int)stats.s_queueStats[i].s_queueDepth; + + wideInt = (Tcl_WideInt)(stats.s_queueStats[i].s_oldestElement); + aQueueStat += wideInt; + + QueueStatList += aQueueStat; + } + result += QueueStatList; + + interp.setResult(result); + return TCL_OK; + +} Added: branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.h =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.h (rev 0) +++ branches/nscldaq-10.2-development/daq/eventbuilder/CInputStatsCommand.h 2012-08-17 17:32:22 UTC (rev 2793) @@ -0,0 +1,81 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2009. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CINPUTSTATSCOMMAND_H +#define __CINPUTSTATSCOMMAND_H + + +#include <TCLObjectProcessor.h> + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + +// Forward definitions: + +class CTCLObject; + + +/** + * @class CInputStatsCommand + * + * This class provides a command that gets the input statistics from + * the event builder fragment queues. The input statistics + * describe the queues in a summary way. + * The command returns a list of the following form: + * \verbatim + * {oldestTimestamp newestTimestamp totalFragcount queue-statistics} + * \endverbatim + * Where: + * - oldestTimestamp is the timestamp of the oldest queued fragment and + * - newestTimestamp is similarly the timestamp of the newest queued fragment. + * - totalFragmentCount is the total number of fragments in all input queues. + * - queue-statistics is itself a list of detailed queue statistics. Each element + * is a sublist containing in order: + * # id - the source id that is putting fragments in this queue. + * # depth - the number of fragments queued in this queue. + * # oldest- the timestamp of the fragment at the front of the queue. + * by the specifications of data sources, this is the + * oldest queued fragment from that data source. + * + */ +class CInputStatsCommand : public CTCLObjectProcessor +{ + // Allowed canonicals. +public: + CInputStatsCommand(CTCLInterpreter& interp, std::string command); + virtual ~CInputStatsCommand(); + + // Forbidden canonicals. +private: + CInputStatsCommand(const CInputStatsCommand&); + CInputStatsCommand& operator=(const CInputStatsCommand&); + int operator==(const CInputStatsCommand&) const; + int operator!=(const CInputStatsCommand&) const; + + // Virtual method overrides: + +public: + virtual int operator()(CTCLInterpreter& interp, std::vector<CTCLObject>& objv); + +}; + + +#endif Modified: branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.am =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.am 2012-08-16 16:07:27 UTC (rev 2792) +++ branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.am 2012-08-17 17:32:22 UTC (rev 2793) @@ -7,7 +7,8 @@ # @THREAD_LDFLAGS@ -libEventBuilder_la_SOURCES = OrdererPackage.cpp CFragmentHandlerCommand.cpp CFragmentHandler.cpp +libEventBuilder_la_SOURCES = OrdererPackage.cpp CFragmentHandlerCommand.cpp CFragmentHandler.cpp \ + CInputStatsCommand.cpp libEventBuilderClient_la_SOURCES=CEventOrderClient.cpp fragment.c \ @@ -24,7 +25,7 @@ CEVBFrameworkApp.h GetOpt.h -noinst_HEADERS = CFragmentHandlerCommand.h CFragmentHandler.h cmdline.h +noinst_HEADERS = CFragmentHandlerCommand.h CFragmentHandler.h cmdline.h CInputStatsCommand.h INCLUDES = -D__STDC_LIMIT_MACROS \ Modified: branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.in =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.in 2012-08-16 16:07:27 UTC (rev 2792) +++ branches/nscldaq-10.2-development/daq/eventbuilder/Makefile.in 2012-08-17 17:32:22 UTC (rev 2793) @@ -81,7 +81,8 @@ @top_builddir@/base/tclplus/libtclPlus.la \ @top_builddir@/base/exception/libException.la am_libEventBuilder_la_OBJECTS = OrdererPackage.lo \ - CFragmentHandlerCommand.lo CFragmentHandler.lo + CFragmentHandlerCommand.lo CFragmentHandler.lo \ + CInputStatsCommand.lo libEventBuilder_la_OBJECTS = $(am_libEventBuilder_la_OBJECTS) libEventBuilderClient_la_DEPENDENCIES = \ @top_builddir@/base/tcpip/libTcp.la \ @@ -269,7 +270,9 @@ #eventorderer_LDFLAGS= @TCL_LDFLAGS@ \ # -Wl,"-rpath=@libdir@" \ # @THREAD_LDFLAGS@ -libEventBuilder_la_SOURCES = OrdererPackage.cpp CFragmentHandlerCommand.cpp CFragmentHandler.cpp +libEventBuilder_la_SOURCES = OrdererPackage.cpp CFragmentHandlerCommand.cpp CFragmentHandler.cpp \ + CInputStatsCommand.cpp + libEventBuilderClient_la_SOURCES = CEventOrderClient.cpp fragment.c \ CEVBClientApp.cpp CEVBFrameworkApp.cpp \ EVBFramework.cpp @@ -279,7 +282,7 @@ include_HEADERS = CEventOrderClient.h fragment.h CEVBClientApp.h EVBFramework.h \ CEVBFrameworkApp.h GetOpt.h -noinst_HEADERS = CFragmentHandlerCommand.h CFragmentHandler.h cmdline.h +noinst_HEADERS = CFragmentHandlerCommand.h CFragmentHandler.h cmdline.h CInputStatsCommand.h INCLUDES = -D__STDC_LIMIT_MACROS \ -I@top_srcdir@/base/tcpip \ -I@top_srcdir@/base/exception \ @@ -414,6 +417,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CEventOrderClient.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CFragmentHandler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CFragmentHandlerCommand.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CInputStatsCommand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EVBFramework.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetOpt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OrdererPackage.Plo@am__quote@ Modified: branches/nscldaq-10.2-development/daq/eventbuilder/OrdererPackage.cpp =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/OrdererPackage.cpp 2012-08-16 16:07:27 UTC (rev 2792) +++ branches/nscldaq-10.2-development/daq/eventbuilder/OrdererPackage.cpp 2012-08-17 17:32:22 UTC (rev 2793) @@ -23,7 +23,9 @@ #include <tcl.h> #include <TCLInterpreter.h> #include "CFragmentHandlerCommand.h" +#include "CInputStatsCommand.h" + static const char* version = "1.0"; // package version string. /** @@ -37,11 +39,12 @@ { Tcl_PkgProvide(pInterp, "EvbOrderer", version); - // Wrapt pInterp in a CTCLInterpretr object and create the command extensions: + // Wrap pInterp in a CTCLInterpretr object and create the command extensions: CTCLInterpreter* pInterpObject = new CTCLInterpreter(pInterp); new CFragmentHandlerCommand(*pInterpObject, "EVB::handleFragment"); + new CInputStatsCommand(*pInterpObject, "EVB::inputStats"); return TCL_OK; } Modified: branches/nscldaq-10.2-development/daq/eventbuilder/eventOrderer.tcl =================================================================== --- branches/nscldaq-10.2-development/daq/eventbuilder/eventOrderer.tcl 2012-08-16 16:07:27 UTC (rev 2792) +++ branches/nscldaq-10.2-development/daq/eventbuilder/eventOrderer.tcl 2012-08-17 17:32:22 UTC (rev 2793) @@ -117,5 +117,27 @@ $EVB::eventBuilder getConnections } - - +## +# EVB::getInputStageStatistics +# +# Get the statistics about the input stage from the event builder +# C++ code. +# This returns directly the output of EVB::inputStats: +# +# \verbatim +# {oldestTimestamp newestTimestamp totalFragcount queue-statistics} +# \endverbatim +# Where: +# - oldestTimestamp is the timestamp of the oldest queued fragment and +# - newestTimestamp is similarly the timestamp of the newest queued fragment. +# - queue-statistics is itself a list of detailed queue statistics. Each element +# is a sublist containing in order: +# # id - the source id that is putting fragments in this queue. +# # depth - the number of fragments queued in this queue. +# # oldest- the timestamp of the fragment at the front of the queue. +# by the specifications of data sources, this is the +# oldest queued fragment from that data source. +# +proc EVB::getInputStageStatistics {} { + return [::EVB::inputStats] +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |