1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
39 #include <anna/core/tracing/Logger.hpp>
41 #include <anna/xml/Node.hpp>
42 #include <anna/xml/Attribute.hpp>
44 #include <anna/timex/Engine.hpp>
46 #include <anna/core/oam/CounterManager.hpp>
47 #include <anna/core/oam/CounterScope.hpp>
48 #include <anna/core/oam/Counter.hpp>
53 #define test_range(index) \
54 if (index < 0 || index >= MaxCounter) { \
55 string msg (asString ()); \
56 msg += functions::asText (" | Index: ", index); \
57 msg += functions::asText (" | Out of range [0, MaxCounter): ", index); \
58 throw RuntimeException (msg, __FILE__, __LINE__); \
61 #define test_instance(index) \
62 if (a_counters [index] == NULL) { \
63 string msg (asString ()); \
64 msg += functions::asText (" | CounterId: ", index); \
65 msg += " | Counter Id is not defined"; \
66 throw RuntimeException (msg, __FILE__, __LINE__); \
70 oam::CounterScope::~CounterScope() {
71 for(int i = 0; i < MaxCounter; i ++) {
72 if(a_counters [i] != NULL)
73 delete a_counters [i];
77 void oam::CounterScope::create(const int counter, const char* name)
78 throw(RuntimeException) {
81 if(a_counters [counter] != NULL) {
82 string msg("Counter '");
85 msg += functions::asString(counter);
86 msg += ") already registered as ";
87 msg += a_counters [counter]->asString();
88 throw RuntimeException(msg, ANNA_FILE_LOCATION);
91 a_counters [counter] = new Counter(*this, counter, name);
93 string msg("Creation | ");
96 msg += a_counters [counter]->asString();
97 Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
101 oam::Counter::type_t oam::CounterScope::increment(const int counter, const oam::Counter::type_t value)
102 throw(RuntimeException) {
104 test_instance(counter);
105 a_counters [counter]->a_value += value;
106 a_counters [counter]->a_accValue += value;
107 LOGINFORMATION(a_counters [counter]->debug());
108 a_counterManager.activateTimer();
109 return a_counters [counter]->a_value;
112 oam::Counter::type_t oam::CounterScope::assign(const int counter, const oam::Counter::type_t value)
113 throw(RuntimeException) {
115 test_instance(counter);
116 a_counters [counter]->a_value = value;
117 a_counters [counter]->a_accValue = value;
118 LOGINFORMATION(a_counters [counter]->debug());
119 a_counterManager.activateTimer();
123 oam::Counter::type_t oam::CounterScope::getValue(const int counter) const
124 throw(RuntimeException) {
126 test_instance(counter);
127 return a_counters [counter]->a_value;
130 Unsigned64 oam::CounterScope::getAccValue(const int counter) const
131 throw(RuntimeException) {
133 test_instance(counter);
134 return a_counters [counter]->a_accValue;
137 int oam::CounterScope::resetAccValues() throw(RuntimeException) {
138 int result = 0; // affected counters
140 for(int ii = 0; ii < MaxCounter; ii ++)
142 result += (a_counters [ii]->resetAcc()) ? 1 : 0;
147 const oam::Counter* oam::CounterScope::getCounter(const int counter) const
148 throw(RuntimeException) {
150 test_instance(counter);
151 return a_counters [counter];
154 string oam::CounterScope::asString() const
156 string result("oam::CounterScope { Id: ");
157 result += functions::asString(a_id);
158 result += " | Name: ";
160 return result += " }";
163 xml::Node* oam::CounterScope::asXML(xml::Node* parent) const
164 throw(RuntimeException) {
165 xml::Node* result = parent->createChild("Scope");
168 for(int ii = 0; ii < MaxCounter; ii ++) {
169 if(a_counters [ii] == NULL)
172 counter = result->createChild("Counter");
173 counter->createAttribute("Id", ii);
174 counter->createAttribute("Name", a_counters [ii]->getName());
175 counter->createAttribute("Value", a_counters [ii]->getValue());
176 counter->createAttribute("AccValue", a_counters [ii]->getAccumulatedValue());
183 [0x7fbfffea90]: timex::Engine | Callers: timex::Engine::activate [2],timex::Engine::tick [69]
184 [0x79bf60, 2]: oam::CounterManager | Callers: MyInterface::receive [4],anna::oam::CounterManager::record [2]
185 [0x7fbfffea90, 2]: timex::Engine | Callers: timex::Engine::activate [2],timex::Engine::tick [69]
186 ------ Loop detected [ Level=2 | Loop: 3 ] -------
188 oam::CounterScope::Safe::Safe(timex::Engine* ttcc, oam::CounterScope& counterScope, const char* whatis) :
189 a_counterScope(counterScope) {
191 a_guards [0] = new Guard(ttcc, "timex::Engine from oam::CounterScope::Safe::Safe");
195 a_guards [1] = new Guard(counterScope, whatis);
198 oam::CounterScope::Safe::~Safe()