blob: a0970373e54d5731e8836f94a1266a2790e2f7ef [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Intel, Mikhail Y. Fursov
*
*/
#ifndef _EVENT_H_
#define _EVENT_H_
namespace Jitrino {
///////////////////////////////////////////////////////////////////////////////
//
// Event objects can be used for debugging purposes as well as to contain the
// amount of optimizations done to put bounds on compile time/space, etc.
// For debugging the client would create an event object and associate it with
// optimization being debugged. On each optimization step the event would be
// incremented. The client would cease to apply the optimization once the
// associated event overflows. With this we can do a binary search to find the
// minimum number of optimization steps needed to cause a failure. Then we can
// generate a "good" and "bad" compilation output that are very close to each
// other thereby enabling easy debug.
//
///////////////////////////////////////////////////////////////////////////////
class Event {
public:
enum State {
Inactive = 0,
Counting,
Overflowed,
Handled,
};
//
// Constructor
//
Event(char *nm) : counter(0), threshold((U_32) -1),
state(Inactive), name(nm) {}
//
// Increment the event counter by reported number of events
//
void reportEvent(int count) {
if (state != Inactive) {
counter += count;
if (counter > threshold && state == Counting)
state = Overflowed;
}
}
//
// Set the state to indicate the event overflow has been handled. Does not
// reset the counter to start counting again. Client has to explicitly call
// startMonitor.
//
void reportHandling() {
assert(state == Overflowed);
state = Handled;
}
//
// Set overflow threshold
//
void setThreshold(U_32 th) { threshold = th; }
//
// Is monitoring active on this event?
//
bool isCounting() { return state == Counting; }
bool isInactive() { return state == Inactive; }
bool isOverflowed() { return state == Overflowed; }
bool isHandled() { return state == Handled; }
//
// Start the event monitoring. Called at the beginning of monitoring and
// after handling an overflow when the client wishes to continue
// monitoring.
//
void startMonitor() {
assert(threshold != ((U_32) -1));
counter = 0;
state = Counting;
}
//
// Stop the event monitoring. Meant to either temporarily or permanently
// suspend monitoring. Event occurrences are reported when event monitoring is
// suspended. They are not counted.
//
void stopMonitor() {
// Monitoring cannot be suspended unless it is in Counting or Overflowed
// states as otherwise we will not know how to reset state upon
// restarting.
assert(state != Handled);
state = Inactive;
}
//
// Restart the event monitoring without resetting the counter to zero.
// Meant for use after a temporary suspension of monitoring. Counting
// continues where it was left off at suspension.
//
void reStartMonitor() {
assert(state == Inactive);
if (counter > threshold)
state = Overflowed;
else
state = Counting;
}
//
// Print data on the event
//
void print(::std::ostream & os) {
os << ::std::endl << "Event: " << name;
os << " State = ";
if (state == Inactive)
os << "Inactive";
else if (state == Counting)
os << "Counting";
else if (state == Overflowed)
os << "Overflowed";
else {
assert(state == Handled);
os << "Handled";
}
os << " Counter = " << (int) counter;
os << " Threshold = " << (int) threshold;
os << ::std::endl;
}
private:
// Fields
U_32 counter; // Counts number of occurrences of the event
U_32 threshold; // Threshold for overflow
State state; // Active indicates that the counter is being tracked
char * name; // Name for the event counter
};
} //namespace Jitrino
#endif // _EVENT_H_