| /* |
| * Copyright © 2012 Linaro Limited |
| * |
| * This file is part of glmark2. |
| * |
| * glmark2 is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, either version 3 of the License, or |
| * (at your option) any later version. |
| * |
| * glmark2 is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with glmark2. If not, see <http://www.gnu.org/licenses/>. |
| * |
| * Authors: |
| * Simon Que <sque@chromium.org> |
| */ |
| |
| #define __STDC_FORMAT_MACROS |
| |
| #include <inttypes.h> |
| #include <stdio.h> |
| #include <sys/time.h> |
| |
| #include "timer.h" |
| #include "util.h" |
| |
| Timer::Timer(int max_cycles, const std::string& name) { |
| data_.resize(max_cycles); |
| |
| timestamp_count_ = 0; |
| cycle_count_ = 0; |
| max_cycles_ = max_cycles; |
| current_cycle_data_ = &data_[0]; |
| |
| timer_list[name] = this; |
| name_ = name; |
| } |
| |
| Timer::~Timer() { |
| timer_list.erase(name_); |
| } |
| |
| void Timer::set_max_timestamps(int max_timestamps) { |
| max_timestamps_ = max_timestamps; |
| for (std::vector<std::vector<uint64_t> >::iterator iter = data_.begin(); |
| iter != data_.end(); ++iter) { |
| (*iter).resize(max_timestamps); |
| } |
| } |
| |
| void Timer::next_cycle() { |
| // However many timestamps have been recorded on the first cycle is the max |
| // number of timestamps allowed on subsequent cycles. |
| if (cycle_count_ == 0) { |
| set_max_timestamps(timestamp_count_); |
| } else if (timestamp_count_ < max_timestamps_) { |
| for (int i = timestamp_count_; i < max_timestamps_; i += 1) |
| (*current_cycle_data_)[i] = |
| (*current_cycle_data_)[timestamp_count_ - 1]; |
| } |
| |
| if (cycle_count_ < max_cycles_) { |
| cycle_count_ += 1; |
| timestamp_count_ = 0; |
| current_cycle_data_ = &data_[cycle_count_]; |
| } |
| } |
| |
| void Timer::read_timestamp(int id) { |
| // Do not read a timestamp if we've exceeded the max number of timestamps |
| // (established by number of calls on cycle 0) or the max number of cycles. |
| if (timestamp_count_ >= max_timestamps_ && cycle_count_ > 0) |
| return; |
| if (cycle_count_ >= max_cycles_) |
| return; |
| |
| // First cycle has no limit to timestamps. |
| // Subsequent cycles must not exceed that number of timestamps. |
| if (cycle_count_ == 0) { |
| timestamp_ids_.push_back(id); |
| data_[0].push_back(Util::get_timestamp_us()); |
| } else { |
| (*current_cycle_data_)[timestamp_count_] = Util::get_timestamp_us(); |
| } |
| timestamp_count_ += 1; |
| } |
| |
| void Timer::print_results() { |
| unsigned int i; |
| int j; |
| for (i = 0; i < timestamp_ids_.size() - 1; i += 1) |
| printf("\t%d", timestamp_ids_[i]); |
| printf("\n"); |
| for (i = 0; i < timestamp_ids_.size(); i += 1) |
| printf("========"); |
| printf("\n"); |
| for (j = 0; j < cycle_count_; j += 1) { |
| std::vector<uint64_t>& current = data_[j]; |
| |
| if (j > 0) |
| printf("%" PRIi64 "", current[0] - data_[j-1][max_timestamps_-1]); |
| for(int i = 0; i < max_timestamps_ - 1; i++) { |
| printf("\t%" PRIi64 "", current[i + 1] - current[i]); |
| } |
| printf("\n"); |
| } |
| } |
| |
| Timer* Timer::get_timer(const std::string& name) { |
| std::map<std::string, Timer*>::const_iterator iter = timer_list.find(name); |
| if (iter == timer_list.end()) |
| return NULL; |
| return iter->second; |
| } |
| |
| std::map<std::string, Timer*> Timer::timer_list; |