Index: native_client_sdk/src/examples/trace_events/trace_events.cc |
diff --git a/native_client_sdk/src/examples/trace_events/trace_events.cc b/native_client_sdk/src/examples/trace_events/trace_events.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2d39316f9eb2908ad6d095205c9e7f7a0f0f8df1 |
--- /dev/null |
+++ b/native_client_sdk/src/examples/trace_events/trace_events.cc |
@@ -0,0 +1,130 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/// @file |
+/// This example demonstrates using Trace Events in a simple NaCl module. |
+/// See documentation here: |
+/// http://www.chromium.org/developers/how-tos/trace-event-profiling-tool/tracing-event-instrumentation |
+/// |
+/// Instead of including <base/debug/trace_event.h>, include |
+/// "ppapi/cpp/dev/trace_event_dev.h" for tracing within PPAPI C++. |
+ |
+#include <pthread.h> |
+#ifdef WIN32 |
+ #include <windows.h> |
+ void sleep_ms(int ms) { |
+ Sleep(ms); |
+ } |
+#else |
+ #include <unistd.h> |
+ void sleep_ms(int ms) { |
+ usleep(ms * 1000); |
+ } |
+#endif |
+ |
+#include <cstdio> |
+#include <sstream> |
+#include <string> |
+ |
+#include "ppapi/cpp/dev/trace_event_dev.h" |
+#include "ppapi/cpp/instance.h" |
+#include "ppapi/cpp/module.h" |
+#include "ppapi/cpp/var.h" |
+ |
+/// Method name for running a task on a new thread, as seen by JavaScript code. |
+const char* const kRunThreadedTask = "runthreadedtask"; |
+ |
+/// Method name to send an async begin trace, as seen by Javascript code. |
+const char* const kSendAsyncBegin = "sendasyncbegin"; |
+ |
+/// Method name to send an async end trace, as seen by Javascript code. |
+const char* const kSendAsyncEnd = "sendasyncend"; |
+ |
+/// The Instance class for the Trace Events example. |
+class TraceEventInstance : public pp::Instance { |
+ public: |
+ explicit TraceEventInstance(PP_Instance instance) : |
+ pp::Instance(instance), |
+ thread_num_(0), |
+ async_num_(0) { |
+ printf("TraceEventInstance.\n"); |
+ } |
+ virtual ~TraceEventInstance() {} |
+ |
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); |
+ |
+ virtual void HandleMessage(const pp::Var& var_message); |
+ |
+ private: |
+ int thread_num_; |
+ int async_num_; |
+}; |
+ |
+void* RunTaskOnThread(void* arg) { |
+ int thread_num = *static_cast<int*>(arg); |
+ std::ostringstream stream; |
+ stream << "Non-main thread #" << thread_num; |
+ pp::Trace_Events::SetThreadName(stream.str().c_str()); |
+ // TRACE_EVENTx traces scope, so will automatically close on function end. |
+ // The '0' variation means that this macro takes zero additional parameters. |
+ TRACE_EVENT0("ExampleCategory", "traceThisSleep"); |
+ sleep_ms(2000); |
+ |
+ return NULL; |
+} |
+ |
+bool TraceEventInstance::Init(uint32_t argc, |
+ const char* argn[], |
+ const char* argv[]) { |
+ // Set a thread name for the main thread, otherwise it shows up as |
+ // a non-descriptive thread-id. |
+ pp::Trace_Events::SetThreadName("Main Pepper Thread"); |
+ return PP_TRUE; |
+} |
+ |
+void TraceEventInstance::HandleMessage(const pp::Var& var_message) { |
+ if (!var_message.is_string()) { |
+ return; |
+ } |
+ std::string message = var_message.AsString(); |
+ pp::Var return_var; |
+ if (message == kRunThreadedTask) { |
+ pthread_t p; |
+ pthread_create(&p, NULL, |
+ RunTaskOnThread, new int(thread_num_)); |
+ thread_num_++; |
+ } else if (message == kSendAsyncBegin) { |
+ // TRACE_EVENT_ASYNC_BEGIN marks the beginning point for a trace event that |
+ // does not end with the scope of the marked location. It must be ended |
+ // with a matching TRACE_EVENT_ASYNC_END call (with matching parameter: |
+ // here, 'async_num_'). |
+ // The '0' variation means that this macro takes zero additional parameters. |
+ TRACE_EVENT_ASYNC_BEGIN0("ExampleCategory", "ExampleMessage", async_num_); |
+ } else if (message == kSendAsyncEnd) { |
+ // Here is the matching call to a previous BEGIN, note that async_num_ is |
+ // incremented after the END call to set up the next BEGIN/END pair. |
+ TRACE_EVENT_ASYNC_END0("ExampleCategory", "ExampleMessage", async_num_); |
+ async_num_++; |
+ } |
+} |
+ |
+/// The Module class. |
+class TraceEventModule : public pp::Module { |
+ public: |
+ TraceEventModule() : pp::Module() { |
+ printf("TraceEventModule.\n"); |
+ } |
+ virtual ~TraceEventModule() {} |
+ |
+ virtual pp::Instance* CreateInstance(PP_Instance instance) { |
+ return new TraceEventInstance(instance); |
+ } |
+}; |
+ |
+ |
+namespace pp { |
+Module* CreateModule() { |
+ return new TraceEventModule(); |
+} |
+} // namespace pp |