1c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org/*
2c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *
4c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *  Use of this source code is governed by a BSD-style license
5c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *  that can be found in the LICENSE file in the root of the source
6c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *  tree. An additional intellectual property rights grant can be found
7c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *  in the file PATENTS.  All contributing project authors may
8c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org */
10c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
11c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
12c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
13c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
14c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
15bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org#include <stdarg.h>
16bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org#include <stdio.h>
17bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org
18c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#include <algorithm>
19c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
20c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
21c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
22c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
23c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgnamespace webrtc {
24c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgnamespace testing {
25c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgnamespace bwe {
26c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
27c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgLogging Logging::g_Logging;
28c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
29cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgstatic std::string ToString(uint32_t v) {
30c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  const size_t kBufferSize = 16;
31c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  char string_buffer[kBufferSize] = {0};
32c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#if defined(_MSC_VER) && defined(_WIN32)
33cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  _snprintf(string_buffer, kBufferSize - 1, "%08x", v);
34c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#else
35cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  snprintf(string_buffer, kBufferSize, "%08x", v);
36c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#endif
37cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  return string_buffer;
38cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
39cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
40cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgLogging::Context::Context(uint32_t name, int64_t timestamp_ms, bool enabled) {
41cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  Logging::GetInstance()->PushState(ToString(name), timestamp_ms, enabled);
42c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
43c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
44c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgLogging::Context::Context(const std::string& name, int64_t timestamp_ms,
45c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org                          bool enabled) {
46cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  Logging::GetInstance()->PushState(name, timestamp_ms, enabled);
47c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
48c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
49c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgLogging::Context::Context(const char* name, int64_t timestamp_ms,
50c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org                          bool enabled) {
51c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  Logging::GetInstance()->PushState(name, timestamp_ms, enabled);
52c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
53c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
54c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgLogging::Context::~Context() {
55c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  Logging::GetInstance()->PopState();
56c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
57c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
58c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgLogging* Logging::GetInstance() {
59c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  return &g_Logging;
60c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
61c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
62cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Logging::SetGlobalContext(uint32_t name) {
63cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
64cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  thread_map_[ThreadWrapper::GetThreadId()].global_state.tag = ToString(name);
65cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
66cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
67cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Logging::SetGlobalContext(const std::string& name) {
68cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
69cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  thread_map_[ThreadWrapper::GetThreadId()].global_state.tag = name;
70cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
71cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
72cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Logging::SetGlobalContext(const char* name) {
73cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
74cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  thread_map_[ThreadWrapper::GetThreadId()].global_state.tag = name;
75cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
76cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
77cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Logging::SetGlobalEnable(bool enabled) {
78cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
79cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  thread_map_[ThreadWrapper::GetThreadId()].global_state.enabled = enabled;
80cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
81cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
82c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgvoid Logging::Log(const char format[], ...) {
83c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
84c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  ThreadMap::iterator it = thread_map_.find(ThreadWrapper::GetThreadId());
85c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  assert(it != thread_map_.end());
86cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  const State& state = it->second.stack.top();
87c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  if (state.enabled) {
88c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    printf("%s\t", state.tag.c_str());
89c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    va_list args;
90c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    va_start(args, format);
91c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    vprintf(format, args);
92c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    va_end(args);
93c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    printf("\n");
94c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  }
95c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
96c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
97c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgvoid Logging::Plot(double value) {
98c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
99c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  ThreadMap::iterator it = thread_map_.find(ThreadWrapper::GetThreadId());
100c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  assert(it != thread_map_.end());
101cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  const State& state = it->second.stack.top();
102c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  if (state.enabled) {
103c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    printf("PLOT\t%s\t%f\t%f\n", state.tag.c_str(), state.timestamp_ms * 0.001,
104c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org           value);
105c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  }
106c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
107c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
108c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgLogging::Logging()
109c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
110c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org      thread_map_() {
111c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
112c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
113cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgLogging::State::State() : tag(""), timestamp_ms(0), enabled(true) {}
114cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
115cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgLogging::State::State(const std::string& tag, int64_t timestamp_ms,
116cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org                      bool enabled)
117cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    : tag(tag),
118cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      timestamp_ms(timestamp_ms),
119cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org      enabled(enabled) {
120cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
121cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
122cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Logging::State::MergePrevious(const State& previous) {
123cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  if (tag == "") {
124cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    tag = previous.tag;
125cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  } else if (previous.tag != "") {
126cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    tag = previous.tag + "_" + tag;
127cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  }
128cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  timestamp_ms = std::max(previous.timestamp_ms, timestamp_ms);
129cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  enabled = previous.enabled && enabled;
130cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org}
131cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org
132cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.orgvoid Logging::PushState(const std::string& append_to_tag, int64_t timestamp_ms,
133c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org                        bool enabled) {
134c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
135cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  State new_state(append_to_tag, timestamp_ms, enabled);
136cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  ThreadState* thread_state = &thread_map_[ThreadWrapper::GetThreadId()];
137cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  std::stack<State>* stack = &thread_state->stack;
138c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  if (stack->empty()) {
139cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    new_state.MergePrevious(thread_state->global_state);
140c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  } else {
141cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    new_state.MergePrevious(stack->top());
142c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  }
143cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  stack->push(new_state);
144c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
145c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
146c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.orgvoid Logging::PopState() {
147c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
148c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  ThreadMap::iterator it = thread_map_.find(ThreadWrapper::GetThreadId());
149c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  assert(it != thread_map_.end());
150cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  std::stack<State>* stack = &it->second.stack;
151cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  int64_t newest_timestamp_ms = stack->top().timestamp_ms;
152cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  stack->pop();
153cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org  if (!stack->empty()) {
154cda3cf3d646f20bb2b785c64c0091868dcc2de5csolenberg@webrtc.org    State* state = &stack->top();
155c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    // Update time so that next log/plot will use the latest time seen so far
156c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    // in this call tree.
157c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org    state->timestamp_ms = std::max(state->timestamp_ms, newest_timestamp_ms);
158c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org  }
159c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}
160c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}  // namespace bwe
161c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}  // namespace testing
162c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org}  // namespace webrtc
163c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org
164c2b61668e22020142791964d3210f6d6da02afa1solenberg@webrtc.org#endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
165