Chromium Code Reviews| Index: native_client_sdk/src/libraries/xray/browser.c |
| diff --git a/native_client_sdk/src/libraries/xray/browser.c b/native_client_sdk/src/libraries/xray/browser.c |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ac8e04aec1abc7af77ebdf35585a12205344a595 |
| --- /dev/null |
| +++ b/native_client_sdk/src/libraries/xray/browser.c |
| @@ -0,0 +1,133 @@ |
| +/* 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. |
| + */ |
| + |
| + |
| +/* XRay -- a simple profiler for Native Client */ |
| + |
| +#ifndef XRAY_DISABLE_BROWSER_INTEGRATION |
| + |
| +#include <alloca.h> |
| +#include <assert.h> |
| +#include <errno.h> |
| +#include <stdarg.h> |
| +#include <stdint.h> |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| +#include <unistd.h> |
| +#include "ppapi/c/dev/ppb_trace_event_dev.h" |
| +#include "xray/xray_priv.h" |
| + |
| + |
| +#if defined(XRAY) |
| +static PPB_Trace_Event_Dev* ppb_trace_event_interface = NULL; |
| + |
| +static const char* XRayGetName(struct XRaySymbolTable* symbols, |
| + struct XRayTraceBufferEntry* e) { |
| + uint32_t addr = XRAY_EXTRACT_ADDR(e->depth_addr); |
| + struct XRaySymbol* symbol = XRaySymbolTableLookup(symbols, addr); |
| + return XRaySymbolGetName(symbol); |
| +} |
| + |
| +struct XRayTimestampPair XRayGenerateTimestampsNow(void) { |
| + struct XRayTimestampPair pair; |
| + assert(ppb_trace_event_interface); |
| + |
| + XRayGetTSC(&pair.xray); |
| + pair.pepper = ppb_trace_event_interface->Now(); |
| + return pair; |
| +} |
| + |
| + |
| +void XRayBrowserTraceReport(struct XRayTraceCapture* capture) { |
| + |
| + const void* cat_enabled = ppb_trace_event_interface->GetCategoryEnabled( |
| + "xray"); |
| + struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture); |
| + |
| + int32_t thread_id = XRayGetSavedThreadID(capture); |
| + |
| + int head = XRayFrameGetHead(capture); |
| + int frame = XRayFrameGetTail(capture); |
| + while(frame != head) { |
| + |
| + struct XRayTimestampPair* start_time = XRayGetTimestamp( |
| + capture, frame, false); |
| + struct XRayTimestampPair* end_time = XRayGetTimestamp( |
| + capture, frame, true); |
|
nfullagar1
2013/07/18 18:21:06
See comment in xray.c about XRayGetTimestamp(...)
grosse
2013/07/18 20:45:37
Done.
|
| + |
| + double pdiff = (end_time->pepper - start_time->pepper); |
| + double odiff = (end_time->xray - start_time->xray); |
| + double scale_a = pdiff / odiff; |
| + double scale_b = ((double)end_time->pepper) - (scale_a * end_time->xray); |
| + printf("Xray timestamp calibration frame %d: %f %f\n", |
| + frame, scale_a, scale_b); |
| + |
| + |
| + int start = XRayFrameGetTraceStartIndex(capture, frame); |
| + int end = XRayFrameGetTraceEndIndex(capture, frame); |
| + int count = XRayFrameGetTraceCount(capture, frame); |
| + |
| + struct XRayTraceBufferEntry** stack_base = XRayMalloc( |
| + sizeof(struct XRayTraceBufferEntry*) * (count+1)); |
|
nfullagar1
2013/07/18 18:21:06
see earlier comment (if new snapshots are uploaded
grosse
2013/07/18 20:45:37
Done.
|
| + struct XRayTraceBufferEntry** stack_top = stack_base; |
| + *stack_top = NULL; |
| + |
| + int i; |
| + for(i = start; i != end; i = XRayTraceNextEntry(capture, i)) { |
|
nfullagar1
2013/07/18 18:21:06
see earlier comment
grosse
2013/07/18 20:45:37
The separate int i; is required for it to compile.
|
| + if (XRayTraceIsAnnotation(capture, i)) { |
| + continue; |
| + } |
| + |
| + uint64_t current_tick = XRayTraceGetEntry(capture, i)->start_tick; |
| + while(*stack_top && current_tick >= (*stack_top)->end_tick) { |
| + struct XRayTraceBufferEntry* e = *(stack_top--); |
| + ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( |
| + 'E', cat_enabled, |
| + XRayGetName(symbols, e), |
| + 0, thread_id, |
| + (scale_a * e->end_tick) + scale_b, |
| + 0, NULL, NULL, NULL, 0 |
| + ); |
| + } |
| + |
| + { |
|
nfullagar1
2013/07/18 18:21:06
see earlier comment
grosse
2013/07/18 20:45:37
Done.
|
| + struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, i); |
| + ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( |
| + 'B', cat_enabled, |
| + XRayGetName(symbols, e), |
| + 0, thread_id, |
| + (scale_a * e->start_tick) + scale_b, |
| + 0, NULL, NULL, NULL, 0 |
| + ); |
| + |
| + *(++stack_top) = e; |
| + } |
| + } |
| + |
| + while(*stack_top) { |
| + struct XRayTraceBufferEntry* e = *(stack_top--); |
| + ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( |
| + 'E', cat_enabled, |
| + XRayGetName(symbols, e), |
| + 0, thread_id, |
| + (scale_a * e->end_tick) + scale_b, |
| + 0, NULL, NULL, NULL, 0 |
| + ); |
| + } |
| + |
| + frame = XRayFrameGetNext(capture, frame); |
| + XRayFree(stack_base); |
| + } |
| +} |
| + |
| +void XRayRegisterBrowserInterface(PPB_GetInterface interface) { |
| + ppb_trace_event_interface = (PPB_Trace_Event_Dev*)interface( |
| + PPB_TRACE_EVENT_DEV_INTERFACE); |
| + assert(ppb_trace_event_interface); |
| +} |
| + |
| +#endif /* XRAY */ |
| +#endif /* XRAY_DISABLE_BROWSER_INTEGRATION */ |