| 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
|
|
|