1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

Merge pull request #23 from daniel-k/xray

Add Xray profiler
This commit is contained in:
Stefan Lankes 2016-05-18 20:01:31 +02:00
commit 3615f393c0
22 changed files with 2336 additions and 64 deletions

View file

@ -41,6 +41,19 @@ ARFLAGS = rsv
RM = rm -rf
OUTPUT_FORMAT = -O elf64-x86-64-hermit
# Additional flags for profiling using Xray
PROFILING_LDFLAGS =
PROFILING_CFLAGS =
ifdef PROFILING
PROFILING_LDFLAGS = -lxray
PROFILING_CFLAGS = -falign-functions=32 -finstrument-functions
PROFILING_CFLAGS += -finstrument-functions-exclude-function-list=_mm_pause,_mm_setcsr,_mm_getcsr # we need this for libiomp to work
PROFILING_CFLAGS += -DXRAY -DXRAY_DISABLE_BROWSER_INTEGRATION -DXRAY_NO_DEMANGLE
PROFILING_CFLAGS += -DXRAY_ANNOTATE
endif
CFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize $(STACKPROT)
FCFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize
FFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize
@ -84,7 +97,9 @@ toolchain:
RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET) \
STRIP_FOR_TARGET=$(STRIP_FOR_TARGET) \
ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) \
READELF_FOR_TARGET=$(READELF_FOR_TARGET) -C usr toolchain
READELF_FOR_TARGET=$(READELF_FOR_TARGET) \
PROFILING_CFLAGS="$(PROFILING_CFLAGS)" \
PROFILING_LDFLAGS="$(PROFILING_LDFLAGS)" -C usr toolchain
bootstrap:
$Q$(MAKE) ARCH=$(ARCH) CFLAGS="" LDFLAGS="" -C usr bootstrap

View file

@ -26,12 +26,12 @@ default:
demo:
@echo Build demo applications
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C tests depend
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C tests
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C benchmarks depend
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C benchmarks
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET) $(PROFILING_CFLAGS)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET) $(PROFILING_LDFLAGS)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C tests depend
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET) $(PROFILING_CFLAGS)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET) $(PROFILING_LDFLAGS)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C tests
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET) $(PROFILING_CFLAGS)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET) $(PROFILING_LDFLAGS)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C benchmarks depend
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET) $(PROFILING_CFLAGS)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET) $(PROFILING_LDFLAGS)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C benchmarks
#$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C openmpbench depend
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C openmpbench
$Q$(MAKE) ELFEDIT_FOR_TARGET=$(ELFEDIT_FOR_TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET) $(PROFILING_CFLAGS)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET) $(PROFILING_LDFLAGS)" OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) -C openmpbench
$(ARCH):
$Q$(MKDIR) $(TMP)
@ -58,13 +58,15 @@ $(TMP)/newlib:
pte:
@echo Build libpthread
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Iplatform/hermit -Iplatform/helper -Wall" -C pte depend
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Iplatform/hermit -Iplatform/helper -Wall" -C pte
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Iplatform/hermit -Iplatform/helper -Wall $(PROFILING_CFLAGS)" -C pte depend
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Iplatform/hermit -Iplatform/helper -Wall $(PROFILING_CFLAGS)" -C pte
libs:
@echo Build Xray profiler
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" LDFLAGS_FOR_TARGET="$(LDFLAGS_FOR_TARGET)" -C xray
@echo Build OpenMP Runtime and iRCCE
$Q$(MAKE) TARGET=$(TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Wall -pthread" -C $(OMPRT) depend
$Q$(MAKE) TARGET=$(TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Wall -pthread" -C $(OMPRT)
$Q$(MAKE) TARGET=$(TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Wall -pthread $(PROFILING_CFLAGS)" -C $(OMPRT) depend
$Q$(MAKE) TARGET=$(TARGET) CXX_FOR_TARGET=$(CXX_FOR_TARGET) CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Wall -pthread $(PROFILING_CFLAGS)" -C $(OMPRT)
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Wall" -C ircce depend
$Q$(MAKE) TARGET=$(TARGET) CC_FOR_TARGET=$(CC_FOR_TARGET) AR_FOR_TARGET=$(AR_FOR_TARGET) CFLAGS_FOR_TARGET+="-I. -Wall" -C ircce
@ -93,6 +95,7 @@ clean:
$Q$(MAKE) -C tests clean
$Q$(MAKE) -C benchmarks clean
$Q$(MAKE) -C openmpbench clean
$Q$(MAKE) -C xray clean
veryclean:
@echo Propper cleaning of the toolchain

View file

@ -52,7 +52,7 @@ stream.o: stream.c
stream: stream.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -fopenmp -o $@ $<
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -fopenmp
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
@ -63,21 +63,21 @@ basic.o: basic.c
basic: basic.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -pthread -o $@ $<
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -pthread
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
RCCE_pingping: RCCE_pingping.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lircce
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -lircce
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
RCCE_pingpong: RCCE_pingpong.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lircce
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -lircce
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
@ -88,14 +88,14 @@ netio.o: netio.c
netio: netio.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $<
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET)
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
hg: hg.o hist.o rdtsc.o run.o init.o opt.o report.o setup.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< hist.o rdtsc.o run.o init.o opt.o report.o setup.o
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) hist.o rdtsc.o run.o init.o opt.o report.o setup.o
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym

2
hermit/usr/openmpbench/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.map
*.xray

View file

@ -6,33 +6,36 @@ CFLAGS_CRAY = ${CFLAGS}
endif
.c.o:
${CC} ${CFLAGS} $(OMPFLAG) -c $*.c
${CC} ${CFLAGS} $(OMPFLAG) -c $*.c
SYNCOBJS = syncbench.o common.o
SCHEDOBJS = schedbench.o common_sched.o
ARRAYOBJS = arraybench_$(IDA).o common.o
TASKOBJS = taskbench.o common.o
SYNCOBJS = syncbench.o common.o
SCHEDOBJS = schedbench.o common_sched.o
ARRAYOBJS = arraybench_$(IDA).o common.o
TASKOBJS = taskbench.o common.o
SCHEDFLAGS = -DSCHEDBENCH
all: syncbench schedbench taskbench
prog: arraybench_$(IDA)
prog: arraybench_$(IDA)
# We need to generate a linker map file so that Xray can resolve function names
LDFLAGS += -Wl,-Map=$@.map
syncbench: $(SYNCOBJS)
$(CC) -o syncbench $(LDFLAGS) $(SYNCOBJS) $(CLOCKOBJS) $(LIBS) -lm
$(CC) -o syncbench $(SYNCOBJS) $(LDFLAGS) $(CLOCKOBJS) $(LIBS) -lm
# Rule to ensure the lower optimisation level is picked up for common.c
# Rule to ensure the lower optimisation level is picked up for common.c
# with the Cray compiler
common.o:
${CC} ${CFLAGS_CRAY} $(OMPFLAG) -c $*.c
common.o:
${CC} ${CFLAGS_CRAY} $(OMPFLAG) -c $*.c
# Separate rule to build common_sched.o as we need to ensure the correct
# DEFAULT_DELAY_TIME is used.
common_sched.o:
# Separate rule to build common_sched.o as we need to ensure the correct
# DEFAULT_DELAY_TIME is used.
common_sched.o:
${CC} ${CFLAGS_CRAY} $(SCHEDFLAGS) $(OMPFLAG) -o common_sched.o -c common.c
schedbench: $(SCHEDOBJS)
$(CC) -o schedbench $(LDFLAGS) $(SCHEDOBJS) $(CLOCKOBJS) $(LIBS) -lm
$(CC) -o schedbench $(SCHEDOBJS) $(LDFLAGS) $(CLOCKOBJS) $(LIBS) -lm
# Multiple header files due to multiple array sizes, makes header file arraybench_*.h
arraybench_$(IDA).h: arraybench.h
@ -44,13 +47,13 @@ arraybench_$(IDA).o: arraybench_$(IDA).h arraybench.c
# Multiple executables due to multiple array sizes, makes exe file arraybench_*
arraybench_$(IDA): $(ARRAYOBJS) $(CLOCKOBJS) arraybench.c
$(CC) $(LDFLAGS) $(ARRAYOBJS) $(CLOCKOBJS) $(LIBS) -lm -o $@
$(CC) -o $@ $(LDFLAGS) $(ARRAYOBJS) $(CLOCKOBJS) $(LIBS) -lm
taskbench: $(TASKOBJS)
$(CC) -o taskbench $(LDFLAGS) $(OMPFLAG) $(TASKOBJS) $(CLOCKOBJS) $(LIBS) -lm
$(CC) -o taskbench $(TASKOBJS) $(LDFLAGS) $(OMPFLAG) $(CLOCKOBJS) $(LIBS) -lm
clean:
-rm -rf *.o syncbench schedbench arraybench_* taskbench
clean:
-rm -rf *.o *.xray *.map syncbench schedbench arraybench_* taskbench
veryclean: clean
-rm -rf OpenMPBench.* *.all

View file

@ -35,6 +35,7 @@
#include <string.h>
#include <math.h>
#include <omp.h>
#include <xray.h>
#include "common.h"
@ -276,6 +277,8 @@ void reference(char *name, void (*refer)(void)) {
int k;
double start;
XRayLabelFrame(name);
// Calculate the required number of innerreps
innerreps = getinnerreps(refer);
@ -319,6 +322,8 @@ void benchmark(char *name, void (*test)(void))
intitest(name);
XRayLabelFrame(name);
for (k=0; k<=outerreps; k++) {
start = getclock();
test();

View file

@ -34,6 +34,7 @@
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#include <xray.h>
#include "common.h"
#include "syncbench.h"
@ -42,6 +43,12 @@ omp_lock_t lock;
int main(int argc, char **argv) {
struct XRayTraceCapture* trace = XRayInit(
20, // max. call depth
32 * 1000 * 1000, // memory for report
13, // frame count
"/hermit/usr/openmpbench/syncbench.map");
// Start Paraver tracing
#ifdef PARAVERTRACE
Extrae_init();
@ -52,48 +59,80 @@ int main(int argc, char **argv) {
omp_init_lock(&lock);
/* GENERATE REFERENCE TIME */
reference("reference time 1", &refer);
XRayStartFrame(trace);
reference("reference time 1", &refer);
XRayEndFrame(trace);
/* TEST PARALLEL REGION */
XRayStartFrame(trace);
benchmark("PARALLEL", &testpr);
XRayEndFrame(trace);
/* TEST FOR */
benchmark("FOR", &testfor);
/* TEST FOR */
XRayStartFrame(trace);
benchmark("FOR", &testfor);
XRayEndFrame(trace);
/* TEST PARALLEL FOR */
benchmark("PARALLEL FOR", &testpfor);
/* TEST PARALLEL FOR */
XRayStartFrame(trace);
benchmark("PARALLEL FOR", &testpfor);
XRayEndFrame(trace);
/* TEST BARRIER */
benchmark("BARRIER", &testbar);
/* TEST BARRIER */
XRayStartFrame(trace);
benchmark("BARRIER", &testbar);
XRayEndFrame(trace);
/* TEST SINGLE */
benchmark("SINGLE", &testsing);
/* TEST SINGLE */
XRayStartFrame(trace);
benchmark("SINGLE", &testsing);
XRayEndFrame(trace);
/* TEST CRITICAL*/
benchmark("CRITICAL", &testcrit);
/* TEST CRITICAL*/
XRayStartFrame(trace);
benchmark("CRITICAL", &testcrit);
XRayEndFrame(trace);
/* TEST LOCK/UNLOCK */
benchmark("LOCK/UNLOCK", &testlock);
/* TEST LOCK/UNLOCK */
XRayStartFrame(trace);
benchmark("LOCK/UNLOCK", &testlock);
XRayEndFrame(trace);
/* TEST ORDERED SECTION */
benchmark("ORDERED", &testorder);
/* TEST ORDERED SECTION */
XRayStartFrame(trace);
benchmark("ORDERED", &testorder);
XRayEndFrame(trace);
/* GENERATE NEW REFERENCE TIME */
reference("reference time 2", &referatom);
/* GENERATE NEW REFERENCE TIME */
XRayStartFrame(trace);
reference("reference time 2", &referatom);
XRayEndFrame(trace);
/* TEST ATOMIC */
benchmark("ATOMIC", &testatom);
/* TEST ATOMIC */
XRayStartFrame(trace);
benchmark("ATOMIC", &testatom);
XRayEndFrame(trace);
/* GENERATE NEW REFERENCE TIME */
reference("reference time 3", &referred);
/* GENERATE NEW REFERENCE TIME */
XRayStartFrame(trace);
reference("reference time 3", &referred);
XRayEndFrame(trace);
/* TEST REDUCTION (1 var) */
benchmark("REDUCTION", &testred);
/* TEST REDUCTION (1 var) */
XRayStartFrame(trace);
benchmark("REDUCTION", &testred);
XRayEndFrame(trace);
#ifdef PARAVERTRACE
Extrae_fini();
#endif
XRaySaveReport(trace,
"/hermit/usr/openmpbench/syncbench.xray", // report file
0.05f, // Only output funcs that have higher runtime [%]
1000); // Only output funcs that have higher runtime [cycles]
XRayShutdown(trace);
finalise();
return EXIT_SUCCESS;
@ -132,6 +171,11 @@ void referred() {
void testpr() {
int j;
#ifdef XRAY
static int n = 1;
XRayAnnotate("n = %i", n);
n++;
#endif
for (j = 0; j < innerreps; j++) {
#pragma omp parallel
{
@ -155,6 +199,11 @@ void testfor() {
void testpfor() {
int i, j;
#ifdef XRAY
static int n = 1;
XRayAnnotate("n = %i", n);
n++;
#endif
for (j = 0; j < innerreps; j++) {
#pragma omp parallel for
for (i = 0; i < nthreads; i++) {

View file

@ -32,7 +32,7 @@ endif
# other implicit rules
%.o : %.c
@echo [CC] $@
$Q$(CC_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) -o $@ $<
$Q$(CC_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) -o $@ $<
%.o: %.cpp
@echo [CXX] $@
@ -48,28 +48,28 @@ all: hello hello++ thr_hello jacobi hellof RCCE_minimum
hello++: hello++.o
@echo [LD] $@
$Q$(CXX_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CXXFLAGS_FOR_TARGET) -o $@ $<
$Q$(CXX_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CXXFLAGS_FOR_TARGET)
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
hello: hello.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $<
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET)
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
hellof: hellof.o
@echo [LD] $@
$Q$(FC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(FFLAGS_FOR_TARGET) -o $@ $<
$Q$(FC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(FFLAGS_FOR_TARGET)
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
jacobi: jacobi.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lm
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET)
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
@ -80,14 +80,14 @@ thr_hello.o: thr_hello.c
thr_hello: thr_hello.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -pthread
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -pthread
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
RCCE_minimum: RCCE_minimum.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< -lircce
$Q$(CC_FOR_TARGET) -o $@ $< $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -lircce
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym

28
hermit/usr/xray/LICENSE Normal file
View file

@ -0,0 +1,28 @@
Copyright 2011, The Chromium Authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

26
hermit/usr/xray/Makefile Normal file
View file

@ -0,0 +1,26 @@
NEWLIB = ../x86/x86_64-hermit
CP = cp
NAME = libxray.a
CC_FOR_TARGET ?= gcc
AR_FOR_TARGET ?= ar
CFLAGS = -DXRAY -DXRAY_DISABLE_BROWSER_INTEGRATION -DXRAY_NO_DEMANGLE -DXRAY_ANNOTATE
CFLAGS += ${CFLAGS_FOR_TARGET}
OBJS = xray.o stringpool.o hashtable.o symtable.o demangle.o parsesymbols.o report.o
$(NAME): $(OBJS)
$(AR_FOR_TARGET) rsv $@ $(OBJS)
$(CP) $@ $(NEWLIB)/lib
$(CP) libxray.spec $(NEWLIB)/lib
$(CP) xray.h $(NEWLIB)/include
%.o: %.c
@echo [CC] $@
@$(CC_FOR_TARGET) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o $(NAME)

163
hermit/usr/xray/browser.c Normal file
View file

@ -0,0 +1,163 @@
/* 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;
}
/* see chromium/src/base/trace_event/trace_event.h */
#define TRACE_VALUE_TYPE_UINT (2)
#define TRACE_VALUE_TYPE_DOUBLE (4)
#define TRACE_VALUE_TYPE_COPY_STRING (7)
union TraceValue {
bool as_bool;
unsigned long long as_uint;
long long as_int;
double as_double;
const void* as_pointer;
const char* as_string;
};
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 = XRayFrameGetStartTimestampPair(
capture, frame);
struct XRayTimestampPair end_time = XRayFrameGetEndTimestampPair(
capture, frame);
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);
struct XRayTraceBufferEntry** stack_base = XRayMalloc(
sizeof(struct XRayTraceBufferEntry*) * (XRAY_TRACE_STACK_SIZE + 1));
struct XRayTraceBufferEntry** stack_top = stack_base;
*stack_top = NULL;
uint32_t num_args = 0;
const char* arg_names[] = {"annotation"};
uint8_t arg_types[] = {TRACE_VALUE_TYPE_COPY_STRING};
uint64_t arg_values[] = {0};
char annotation[XRAY_TRACE_ANNOTATION_LENGTH];
int i;
for(i = start; i != end; i = XRayTraceNextEntry(capture, i)) {
if (XRayTraceIsAnnotation(capture, i)) {
continue;
}
uint32_t depth = XRAY_EXTRACT_DEPTH(
XRayTraceGetEntry(capture, i)->depth_addr);
while(*stack_top &&
XRAY_EXTRACT_DEPTH((*stack_top)->depth_addr) >= depth) {
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
);
}
num_args = 0;
struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, i);
uint32_t annotation_index = e->annotation_index;
if (annotation_index) {
XRayTraceCopyToString(capture, annotation_index, annotation);
union TraceValue val;
val.as_string = (const char*)annotation;
arg_values[0] = val.as_uint;
num_args = 1;
}
ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp(
'B', cat_enabled,
XRayGetName(symbols, e),
0, thread_id,
(scale_a * e->start_tick) + scale_b,
num_args, arg_names, arg_types, arg_values, 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 */

View file

@ -0,0 +1,25 @@
/* 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. */
#include "xray_priv.h"
/* Note name demangling requires linking against libstdc++ */
/* If your platform does not support __cxa_demangle, re-compile XRay with: */
/* -DXRAY_NO_DEMANGLE */
#if !defined(XRAY_NO_DEMANGLE)
extern
char* __cxa_demangle(const char* __mangled_name, char* __output_buffer,
size_t* __length, int* __status);
#endif
const char* XRayDemangle(char* demangle, size_t size, const char* symbol) {
#if !defined(XRAY_NO_DEMANGLE)
int stat;
__cxa_demangle(symbol, demangle, &size, &stat);
if (stat == 0)
return demangle;
#endif
return symbol;
}

205
hermit/usr/xray/hashtable.c Normal file
View file

@ -0,0 +1,205 @@
/* 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. */
/* Hashtable for XRay */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xray_priv.h"
#if defined(XRAY)
struct XRayHashTableEntry {
void* data;
uint32_t key;
};
struct XRayHashTable {
int capacity;
int count;
struct XRayHashTableEntry* array;
};
XRAY_NO_INSTRUMENT void XRayHashTableGrow(struct XRayHashTable* table);
XRAY_NO_INSTRUMENT uint32_t XRayHashTableHashKey(uint32_t key);
XRAY_NO_INSTRUMENT void XRayHashTableInit(struct XRayHashTable* table,
int32_t capacity);
#define HASH_HISTO 1024
int g_hash_histo[HASH_HISTO];
/* Hashes a 32bit key into a 32bit value. */
uint32_t XRayHashTableHashKey(uint32_t x) {
uint32_t y = x * 7919;
uint32_t z;
size_t c;
uint8_t* s = (uint8_t*)&y;
/* based on djb2 hash function */
uint32_t h = 5381;
for (c = 0; c < sizeof(y); ++c) {
z = s[c];
h = ((h << 5) + h) + z;
}
return h;
}
int XRayHashTableGetCapacity(struct XRayHashTable* table) {
return table->capacity;
}
int XRayHashTableGetCount(struct XRayHashTable* table) {
return table->count;
}
/* Looks up key in hashtable and returns blind data. */
void* XRayHashTableLookup(struct XRayHashTable* table, uint32_t key) {
uint32_t h = XRayHashTableHashKey(key);
uint32_t m = table->capacity - 1;
uint32_t j = h & m;
uint32_t i;
int z = 1;
for (i = 0; i < m; ++i) {
/* An empty entry means the {key, data} isn't in the table. */
if (NULL == table->array[j].data) {
++g_hash_histo[0];
return NULL;
}
/* Search for address */
if (table->array[j].key == key) {
if (z >= HASH_HISTO)
z = HASH_HISTO - 1;
++g_hash_histo[z];
return table->array[j].data;
}
j = (j + 1) & m;
++z;
}
/* Table was full, and there wasn't a match. */
return NULL;
}
/* Inserts key & data into hash table. No duplicates. */
void* XRayHashTableInsert(struct XRayHashTable* table,
void* data, uint32_t key) {
uint32_t h = XRayHashTableHashKey(key);
uint32_t m = table->capacity - 1;
uint32_t j = h & m;
uint32_t i;
for (i = 0; i < m; ++i) {
/* Take the first empty entry. */
/* (the key,data isn't already in the table) */
if (NULL == table->array[j].data) {
void* ret;
float ratio;
table->array[j].data = data;
table->array[j].key = key;
++table->count;
ret = data;
ratio = (float)table->count / (float)table->capacity;
/* Double the capacity of the symtable if we've hit the ratio. */
if (ratio > XRAY_SYMBOL_TABLE_MAX_RATIO)
XRayHashTableGrow(table);
return ret;
}
/* If the key is already present, return the data in the table. */
if (table->array[j].key == key) {
return table->array[j].data;
}
j = (j + 1) & m;
}
/* Table was full */
return NULL;
}
void* XRayHashTableAtIndex(struct XRayHashTable* table, int i) {
if ((i < 0) || (i >= table->capacity))
return NULL;
return table->array[i].data;
}
/* Grows the hash table by doubling its capacity, */
/* then re-inserts all the elements into the new table. */
void XRayHashTableGrow(struct XRayHashTable* table) {
struct XRayHashTableEntry* old_array = table->array;
int old_capacity = table->capacity;
int new_capacity = old_capacity * 2;
int i;
printf("XRay: Growing a hash table...\n");
XRayHashTableInit(table, new_capacity);
for (i = 0; i < old_capacity; ++i) {
void* data = old_array[i].data;
if (NULL != data) {
uint32_t key = old_array[i].key;
XRayHashTableInsert(table, data, key);
}
}
XRayFree(old_array);
}
void XRayHashTableInit(struct XRayHashTable* table, int32_t capacity) {
size_t bytes;
if (0 != (capacity & (capacity - 1))) {
printf("Xray: Hash table capacity should be a power of 2!\n");
/* Round capacity up to next power of 2 */
/* see http://aggregate.org/MAGIC/ */
capacity--;
capacity |= capacity >> 1;
capacity |= capacity >> 2;
capacity |= capacity >> 4;
capacity |= capacity >> 8;
capacity |= capacity >> 16;
capacity++;
}
bytes = sizeof(table->array[0]) * capacity;
table->capacity = capacity;
table->count = 0;
table->array = (struct XRayHashTableEntry*)XRayMalloc(bytes);
}
/* Creates & inializes hash table. */
struct XRayHashTable* XRayHashTableCreate(int capacity) {
struct XRayHashTable* table;
table = (struct XRayHashTable*)XRayMalloc(sizeof(*table));
XRayHashTableInit(table, capacity);
memset(&g_hash_histo[0], 0, sizeof(g_hash_histo[0]) * HASH_HISTO);
return table;
}
/* Prints hash table performance to file; for debugging. */
void XRayHashTableHisto(FILE* f) {
int i;
for (i = 0; i < HASH_HISTO; ++i) {
if (0 != g_hash_histo[i])
fprintf(f, "hash_iterations[%d] = %d\n", i, g_hash_histo[i]);
}
}
/* Frees hash table. */
/* Note: Does not free what the hash table entries point to. */
void XRayHashTableFree(struct XRayHashTable* table) {
XRayFree(table->array);
table->capacity = 0;
table->count = 0;
table->array = NULL;
XRayFree(table);
}
#endif /* XRAY */

View file

@ -0,0 +1,3 @@
# Do we really need this? Does this even what we want?
*link_xray: -lxray

View file

@ -0,0 +1,96 @@
/* 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 */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xray_priv.h"
#if defined(XRAY)
struct XRaySymbol* XRaySymbolTableCreateEntry(struct XRaySymbolTable* symtab,
char* line) {
uint32_t addr;
unsigned int uiaddr;
char symbol_text[XRAY_LINE_SIZE];
char* parsed_symbol;
char* newln;
if (2 != sscanf(line, "%x %1023s", &uiaddr, symbol_text))
return NULL;
if (uiaddr > 0x07FFFFFF) {
fprintf(stderr, "While parsing the mapfile, XRay encountered:\n");
fprintf(stderr, "%s\n", line);
fprintf(stderr,
"XRay only works with code addresses 0x00000000 - 0x07FFFFFF\n");
fprintf(stderr, "All functions must reside in this address space.\n");
exit(-1);
}
addr = (uint32_t)uiaddr;
parsed_symbol = strstr(line, symbol_text);
newln = strstr(parsed_symbol, "\n");
if (NULL != newln) {
*newln = 0;
}
return XRaySymbolTableAddByName(symtab, parsed_symbol, addr);
}
void XRaySymbolTableParseMapfile(struct XRaySymbolTable* symtab,
const char* mapfile) {
FILE* f;
char line[XRAY_LINE_SIZE];
bool in_text = false;
bool in_link_once = false;
int in_link_once_counter = 0;
int num_symbols = 0;
printf("XRay: opening mapfile %s\n", mapfile);
f = fopen(mapfile, "rt");
if (0 == f) {
fprintf(stderr, "XRay: failed to open %s\n", mapfile);
return;
}
printf("XRay: parsing...\n");
while (NULL != fgets(line, XRAY_LINE_SIZE, f)) {
if (line == strstr(line, " .text ")) {
in_text = true;
continue;
}
if (line == strstr(line, " .gnu.linkonce.t.")) {
in_link_once = true;
in_link_once_counter = 0;
continue;
}
if (line == strstr(line, " .text.")) {
in_link_once = true;
in_link_once_counter = 0;
continue;
}
if (line == strstr(line, " 0x")) {
if (in_text) {
XRaySymbolTableCreateEntry(symtab, line);
++num_symbols;
} else if (in_link_once) {
if (in_link_once_counter != 0) {
if (NULL != XRaySymbolTableCreateEntry(symtab, line))
++num_symbols;
} else {
++in_link_once_counter;
}
}
} else {
in_text = false;
in_link_once = false;
}
}
fclose(f);
printf("XRay: parsed %d symbols into symbol table\n", num_symbols);
}
#endif // XRAY

211
hermit/usr/xray/report.c Normal file
View file

@ -0,0 +1,211 @@
/* 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 */
#include <alloca.h>
#include <errno.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xray_priv.h"
#if defined(XRAY)
struct XRayTotal {
int index;
int frame;
uint64_t ticks;
};
/* Dumps the trace report for a given frame. */
void XRayTraceReport(struct XRayTraceCapture* capture,
FILE* f,
int frame,
char* label,
float percent_cutoff,
int ticks_cutoff) {
int index;
int start;
int end;
float total;
char space[257];
struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture);
memset(space, ' ', 256);
space[256] = 0;
if (NULL == f) {
f = stdout;
}
fprintf(f,
"====================================================================\n");
if (NULL != label)
fprintf(f, "label %s\n", label);
fprintf(f, "\n");
fprintf(f,
" Address Ticks Percent Function [annotation...]\n");
fprintf(f,
"--------------------------------------------------------------------\n");
total = XRayFrameGetTotalTicks(capture, frame);
start = XRayFrameGetTraceStartIndex(capture, frame);
end = XRayFrameGetTraceEndIndex(capture, frame);
index = start;
while (index != end) {
if (!XRayTraceIsAnnotation(capture, index)) {
const char* symbol_name;
char annotation[XRAY_TRACE_ANNOTATION_LENGTH];
struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, index);
uint32_t depth = XRAY_EXTRACT_DEPTH(e->depth_addr);
uint32_t addr = XRAY_EXTRACT_ADDR(e->depth_addr);
uint32_t annotation_index = e->annotation_index;
uint64_t ticks =
e->end_tick > e->start_tick ? e->end_tick - e->start_tick : 0;
float percent = 100.0f * (float)ticks / total;
if (percent >= percent_cutoff && ticks >= ticks_cutoff) {
struct XRaySymbol* symbol;
symbol = XRaySymbolTableLookup(symbols, addr);
symbol_name = XRaySymbolGetName(symbol);
if (0 != annotation_index) {
XRayTraceCopyToString(capture, annotation_index, annotation);
} else {
strcpy(annotation, "");
}
fprintf(f, "0x%08X %12" PRIu64 " %5.1f %s%s %s\n",
(unsigned int)addr, ticks, percent,
&space[256 - depth], symbol_name, annotation);
}
}
index = XRayTraceNextEntry(capture, index);
}
fflush(f);
}
int qcompare(const void* a, const void* b) {
struct XRayTotal* ia = (struct XRayTotal*)a;
struct XRayTotal* ib = (struct XRayTotal*)b;
if (ib->ticks > ia->ticks)
return 1;
else if (ib->ticks < ia->ticks)
return -1;
return 0;
}
/* Dumps a frame report */
void XRayFrameReport(struct XRayTraceCapture* capture, FILE* f) {
int i;
int head = XRayFrameGetHead(capture);
int frame = XRayFrameGetTail(capture);
int counter = 0;
int total_capture = 0;
struct XRayTotal* totals;
totals = (struct XRayTotal*)
alloca(XRayFrameGetCount(capture) * sizeof(struct XRayTotal));
fprintf(f, "\n");
fprintf(f,
"Frame# Total Ticks Capture size Annotations Label\n");
fprintf(f,
"--------------------------------------------------------------------\n");
while (frame != head) {
uint64_t total_ticks = XRayFrameGetTotalTicks(capture, frame);
int capture_size = XRayFrameGetTraceCount(capture, frame);
int annotation_count = XRayFrameGetAnnotationCount(capture, frame);
bool valid = XRayFrameIsValid(capture, frame);
char label[XRAY_MAX_LABEL];
XRayFrameMakeLabel(capture, counter, label);
fprintf(f, " %3d %s %12" PRIu64 " %10d %10d %s\n",
counter,
valid ? " " : "*",
total_ticks,
capture_size,
annotation_count,
label);
totals[counter].index = counter;
totals[counter].frame = frame;
totals[counter].ticks = total_ticks;
total_capture += capture_size;
++counter;
frame = XRayFrameGetNext(capture, frame);
}
fprintf(f,
"--------------------------------------------------------------------\n");
fprintf(f,
"XRay: %d frame(s) %d total capture(s)\n", counter, total_capture);
fprintf(f, "\n");
/* Sort and take average of the median cut */
qsort(totals, counter, sizeof(struct XRayTotal), qcompare);
fprintf(f, "\n");
fprintf(f, "Sorted by total ticks (most expensive first):\n");
fprintf(f, "\n");
fprintf(f,
"Frame# Total Ticks Capture size Annotations Label\n");
fprintf(f,
"--------------------------------------------------------------------\n");
for (i = 0; i < counter; ++i) {
int index = totals[i].index;
int frame = totals[i].frame;
uint64_t total_ticks = XRayFrameGetTotalTicks(capture, frame);
int capture_size = XRayFrameGetTraceCount(capture, frame);
int annotation_count = XRayFrameGetAnnotationCount(capture, frame);
char label[XRAY_MAX_LABEL];
XRayFrameMakeLabel(capture, index, label);
fprintf(f, " %3d %12" PRIu64 " %10d %10d %s\n",
index,
total_ticks,
capture_size,
annotation_count,
label);
}
fflush(f);
}
/* Dump a frame report followed by trace report(s) for each frame. */
void XRayReport(struct XRayTraceCapture* capture,
FILE* f,
float percent_cutoff,
int ticks_cutoff) {
int head = XRayFrameGetHead(capture);
int frame = XRayFrameGetTail(capture);
int counter = 0;
XRayFrameReport(capture, f);
fprintf(f, "\n");
while (frame != head) {
char label[XRAY_MAX_LABEL];
fprintf(f, "\n");
XRayFrameMakeLabel(capture, counter, label);
XRayTraceReport(capture, f, frame, label, percent_cutoff, ticks_cutoff);
++counter;
frame = XRayFrameGetNext(capture, frame);
}
fprintf(f,
"====================================================================\n");
#if defined(XRAY_OUTPUT_HASH_COLLISIONS)
XRayHashTableHisto(capture, f);
#endif
fflush(f);
}
/* Write a profile report to text file. */
void XRaySaveReport(struct XRayTraceCapture* capture,
const char* filename,
float percent_cutoff,
int ticks_cutoff) {
FILE* f;
f = fopen(filename, "w");
if (NULL != f) {
XRayReport(capture, f, percent_cutoff, ticks_cutoff);
fclose(f);
} else {
printf("Cannot open file '%s'\n", filename);
}
}
#endif /* XRAY */

View file

@ -0,0 +1,94 @@
/* 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 string pool */
/* String pool holds a large pile of strings. */
/* It is up to higher level data structures to avoid duplicates. */
/* It is up to higher level data structures to provide fast lookups. */
/* _GNU_SOURCE must be defined prior to the inclusion of string.h
* so that strnlen is available with glibc */
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include "xray_priv.h"
#if defined(XRAY)
struct XRayStringPoolNode {
struct XRayStringPoolNode* next;
char strings[XRAY_STRING_POOL_NODE_SIZE];
};
struct XRayStringPool {
struct XRayStringPoolNode* head;
struct XRayStringPoolNode* current;
int index;
};
static struct XRayStringPoolNode* XRayStringPoolAllocNode() {
struct XRayStringPoolNode* s;
s = (struct XRayStringPoolNode *)XRayMalloc(sizeof(*s));
s->next = NULL;
return s;
}
static int XRayStringPoolCurrentNodeSpaceAvail(struct XRayStringPool* pool) {
int i = pool->index;
return (XRAY_STRING_POOL_NODE_SIZE - i) - 1;
}
/* Append a string to the string pool. */
char* XRayStringPoolAppend(struct XRayStringPool* pool, const char* src) {
/* Add +1 to STRING_POOL_NODE_SIZE to detect large strings */
/* Add +1 to strnlen result to account for string termination */
int n = strnlen(src, XRAY_STRING_POOL_NODE_SIZE + 1) + 1;
int a = XRayStringPoolCurrentNodeSpaceAvail(pool);
char* dst;
/* Don't accept strings larger than the pool node. */
if (n >= (XRAY_STRING_POOL_NODE_SIZE - 1))
return NULL;
/* If string doesn't fit, alloc a new node. */
if (n > a) {
pool->current->next = XRayStringPoolAllocNode();
pool->current = pool->current->next;
pool->index = 0;
}
/* Copy string and return a pointer to copy. */
dst = &pool->current->strings[pool->index];
strcpy(dst, src);
pool->index += n;
return dst;
}
/* Create & initialize a string pool instance. */
struct XRayStringPool* XRayStringPoolCreate() {
struct XRayStringPool* pool;
pool = (struct XRayStringPool*)XRayMalloc(sizeof(*pool));
pool->head = XRayStringPoolAllocNode();
pool->current = pool->head;
return pool;
}
/* Free a string pool. */
void XRayStringPoolFree(struct XRayStringPool* pool) {
struct XRayStringPoolNode* n = pool->head;
while (NULL != n) {
struct XRayStringPoolNode* c = n;
n = n->next;
XRayFree(c);
}
XRayFree(pool);
}
#endif /* XRAY */

200
hermit/usr/xray/symtable.c Normal file
View file

@ -0,0 +1,200 @@
/* 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 symbol table */
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__GLIBC__)
#include <dlfcn.h>
#endif
#include "xray_priv.h"
#define PNACL_STRING_OFFSET (0x10000000)
#if defined(XRAY)
bool g_symtable_debug = false;
struct XRayFrameInfo {
int times_called;
int total_ticks;
};
struct XRaySymbol {
const char* name;
struct XRayFrameInfo frames[XRAY_MAX_FRAMES];
};
struct XRaySymbolPoolNode {
struct XRaySymbolPoolNode* next;
struct XRaySymbol symbols[XRAY_SYMBOL_POOL_NODE_SIZE];
};
struct XRaySymbolPool {
struct XRaySymbolPoolNode* head;
struct XRaySymbolPoolNode* current;
int index;
};
struct XRaySymbolTable {
int num_symbols;
struct XRayHashTable* hash_table;
struct XRayStringPool* string_pool;
struct XRaySymbolPool* symbol_pool;
};
const char* XRaySymbolGetName(struct XRaySymbol* symbol) {
return (NULL == symbol) ? "(null)" : symbol->name;
}
struct XRaySymbol* XRaySymbolCreate(struct XRaySymbolPool* sympool,
const char* name)
{
struct XRaySymbol* symbol;
symbol = XRaySymbolPoolAlloc(sympool);
symbol->name = name;
return symbol;
}
struct XRaySymbol* XRaySymbolPoolAlloc(struct XRaySymbolPool* sympool) {
struct XRaySymbol* symbol;
if (sympool->index >= XRAY_SYMBOL_POOL_NODE_SIZE) {
struct XRaySymbolPoolNode* new_pool;
new_pool = (struct XRaySymbolPoolNode*)XRayMalloc(sizeof(*new_pool));
sympool->current->next = new_pool;
sympool->current = new_pool;
sympool->index = 0;
}
symbol = &sympool->current->symbols[sympool->index];
++sympool->index;
return symbol;
}
struct XRaySymbolPool* XRaySymbolPoolCreate() {
struct XRaySymbolPool* sympool;
struct XRaySymbolPoolNode* node;
sympool = (struct XRaySymbolPool*)XRayMalloc(sizeof(*sympool));
node = (struct XRaySymbolPoolNode*)XRayMalloc(sizeof(*node));
sympool->head = node;
sympool->current = node;
sympool->index = 0;
return sympool;
}
void XRaySymbolPoolFree(struct XRaySymbolPool* pool) {
struct XRaySymbolPoolNode* n = pool->head;
while (NULL != n) {
struct XRaySymbolPoolNode* c = n;
n = n->next;
XRayFree(c);
}
XRayFree(pool);
}
int XRaySymbolTableGetCount(struct XRaySymbolTable* symtab) {
return XRayHashTableGetCount(symtab->hash_table);
}
struct XRaySymbol* XRaySymbolTableAtIndex(struct XRaySymbolTable* symtab,
int i) {
return (struct XRaySymbol*)XRayHashTableAtIndex(symtab->hash_table, i);
}
struct XRaySymbol* XRaySymbolTableAdd(struct XRaySymbolTable* symtab,
struct XRaySymbol* symbol,
uint32_t addr) {
struct XRaySymbol* sym = (struct XRaySymbol*)
XRayHashTableInsert(symtab->hash_table, symbol, addr);
symtab->num_symbols = XRayHashTableGetCount(symtab->hash_table);
return sym;
}
struct XRaySymbol* XRaySymbolTableAddByName(struct XRaySymbolTable* symtab,
const char* name, uint32_t addr) {
char* recorded_name;
struct XRaySymbol* symbol;
char buffer[XRAY_LINE_SIZE];
const char* demangled_name = XRayDemangle(buffer, XRAY_LINE_SIZE, name);
/* record the demangled symbol name into the string pool */
recorded_name = XRayStringPoolAppend(symtab->string_pool, demangled_name);
if (g_symtable_debug)
printf("adding symbol %s\n", recorded_name);
/* construct a symbol and put it in the symbol table */
symbol = XRaySymbolCreate(symtab->symbol_pool, recorded_name);
return XRaySymbolTableAdd(symtab, symbol, addr);
}
struct XRaySymbol* XRaySymbolTableLookup(struct XRaySymbolTable* symtab,
uint32_t addr) {
void *x = XRayHashTableLookup(symtab->hash_table, addr);
struct XRaySymbol* r = (struct XRaySymbol*)x;
#if defined(__pnacl__)
if (r == NULL) {
/* Addresses are trimed to 24 bits for internal storage, so we need to
* add this offset back in order to get the real address.
*/
addr |= PNACL_STRING_OFFSET;
const char* name = (const char*)addr;
struct XRaySymbol* symbol = XRaySymbolCreate(symtab->symbol_pool, name);
r = XRaySymbolTableAdd(symtab, symbol, addr);
}
#endif
#if defined(__GLIBC__)
if (r == NULL) {
Dl_info info;
if (dladdr((const void*)addr, &info) != 0)
if (info.dli_sname)
r = XRaySymbolTableAddByName(symtab, info.dli_sname, addr);
}
#endif
return r;
}
/* Returns total number of symbols in the table. */
int XRaySymbolCount(struct XRaySymbolTable* symtab) {
return symtab->num_symbols;
}
/* Creates and inializes a symbol table. */
struct XRaySymbolTable* XRaySymbolTableCreate(int size) {
struct XRaySymbolTable* symtab;
symtab = (struct XRaySymbolTable*)XRayMalloc(sizeof(*symtab));
symtab->num_symbols = 0;
symtab->string_pool = XRayStringPoolCreate();
symtab->hash_table = XRayHashTableCreate(size);
symtab->symbol_pool = XRaySymbolPoolCreate();
return symtab;
}
/* Frees a symbol table. */
void XRaySymbolTableFree(struct XRaySymbolTable* symtab) {
XRayStringPoolFree(symtab->string_pool);
XRaySymbolPoolFree(symtab->symbol_pool);
XRayHashTableFree(symtab->hash_table);
symtab->num_symbols = 0;
XRayFree(symtab);
}
#endif /* XRAY */

809
hermit/usr/xray/xray.c Normal file
View file

@ -0,0 +1,809 @@
/* 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 */
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "xray_priv.h"
#if defined(XRAY)
/* GTSC - Get Time Stamp Counter */
#if defined(__amd64__) && !defined(XRAY_NO_RDTSC)
XRAY_INLINE uint64_t RDTSC64();
uint64_t RDTSC64() {
uint64_t a, d;
__asm__ __volatile__("rdtsc" : "=a" (a), "=d" (d));
return ((uint64_t)a) | (((uint64_t)d) << 32);
}
#define GTSC(_x) _x = RDTSC64()
#elif defined(__i386__) && !defined(XRAY_NO_RDTSC)
#define GTSC(_x) __asm__ __volatile__ ("rdtsc" : "=A" (_x));
#else
XRAY_INLINE uint64_t GTOD();
uint64_t GTOD() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
}
#define GTSC(_x) _x = GTOD();
#endif
/* Use a TLS variable for cheap thread uid. */
__thread struct XRayTraceCapture* g_xray_capture = NULL;
__thread int g_xray_thread_id_placeholder = 0;
struct XRayTraceStackEntry {
uint32_t depth_addr;
uint64_t tsc;
uint32_t dest;
uint32_t annotation_index;
};
struct XRayTraceFrameEntry {
/* Indices into global tracebuffer */
int start;
int end;
uint64_t start_tsc;
uint64_t end_tsc;
uint64_t total_ticks;
int annotation_count;
bool valid;
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
struct XRayTimestampPair start_time;
struct XRayTimestampPair end_time;
#endif
};
struct XRayTraceFrame {
struct XRayTraceFrameEntry* entry;
int head;
int tail;
int count;
};
struct XRayTraceCapture {
/* Common variables share cache line */
bool recording;
uint32_t stack_depth;
uint32_t max_stack_depth;
int buffer_index;
int buffer_size;
int disabled;
int annotation_count;
struct XRaySymbolTable* symbols;
bool initialized;
uint32_t annotation_filter;
uint32_t guard0;
struct XRayTraceStackEntry stack[XRAY_TRACE_STACK_SIZE] XRAY_ALIGN64;
uint32_t guard1;
uint32_t guard2;
char annotation[XRAY_ANNOTATION_STACK_SIZE] XRAY_ALIGN64;
uint32_t guard3;
struct XRayTraceBufferEntry* buffer;
struct XRayTraceFrame frame;
char frame_labels[XRAY_FRAME_LBL_BUFSIZE][XRAY_MAX_LABEL];
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
int32_t thread_id;
#endif
} XRAY_ALIGN64;
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__pnacl__)
XRAY_NO_INSTRUMENT void __pnacl_profile_func_enter(const char* fname);
XRAY_NO_INSTRUMENT void __pnacl_profile_func_exit(const char* fname);
#else
XRAY_NO_INSTRUMENT void __cyg_profile_func_enter(void* this_fn,
void* call_site);
XRAY_NO_INSTRUMENT void __cyg_profile_func_exit(void* this_fn,
void* call_site);
#endif
XRAY_INLINE int XRayTraceDecrementIndexInline(
struct XRayTraceCapture* capture, int index);
XRAY_INLINE int XRayTraceIncrementIndexInline(
struct XRayTraceCapture* capture, int index);
XRAY_NO_INSTRUMENT void __xray_profile_append_annotation(
struct XRayTraceCapture* capture,
struct XRayTraceStackEntry* se,
struct XRayTraceBufferEntry* be);
#ifdef __cplusplus
}
#endif
/* Asserts that the guard values haven't changed. */
void XRayCheckGuards(struct XRayTraceCapture* capture) {
assert(capture->guard0 == XRAY_GUARD_VALUE_0x12345678);
assert(capture->guard1 == XRAY_GUARD_VALUE_0x12345678);
assert(capture->guard2 == XRAY_GUARD_VALUE_0x87654321);
assert(capture->guard3 == XRAY_GUARD_VALUE_0x12345678);
}
/* Decrements the trace index, wrapping around if needed. */
int XRayTraceDecrementIndexInline(
struct XRayTraceCapture* capture, int index) {
--index;
if (index < 0)
index = capture->buffer_size - 1;
return index;
}
/* Increments the trace index, wrapping around if needed. */
int XRayTraceIncrementIndexInline(
struct XRayTraceCapture* capture, int index) {
++index;
if (index >= capture->buffer_size)
index = 0;
return index;
}
/* Returns true if the trace entry is an annotation string. */
bool XRayTraceIsAnnotation(
struct XRayTraceCapture* capture, int index) {
struct XRayTraceBufferEntry* be = &capture->buffer[index];
char* dst = (char*)be;
return 0 == *dst;
}
int XRayTraceIncrementIndex(struct XRayTraceCapture* capture, int index) {
return XRayTraceIncrementIndexInline(capture, index);
}
int XRayTraceDecrementIndex(struct XRayTraceCapture* capture, int index) {
return XRayTraceDecrementIndexInline(capture, index);
}
/* The entry in the tracebuffer at index is an annotation string. */
/* Calculate the next index value representing the next trace entry. */
int XRayTraceSkipAnnotation(struct XRayTraceCapture* capture, int index) {
/* Annotations are strings embedded in the trace buffer. */
/* An annotation string can span multiple trace entries. */
/* Skip over the string by looking for zero termination. */
assert(capture);
assert(XRayTraceIsAnnotation(capture, index));
bool done = false;
int start_index = 1;
int i;
while (!done) {
char* str = (char*) &capture->buffer[index];
const int num = sizeof(capture->buffer[index]);
for (i = start_index; i < num; ++i) {
if (0 == str[i]) {
done = true;
break;
}
}
index = XRayTraceIncrementIndexInline(capture, index);
start_index = 0;
}
return index;
}
struct XRayTraceBufferEntry* XRayTraceGetEntry(
struct XRayTraceCapture* capture, int index) {
return &capture->buffer[index];
}
/* Starting at index, return the index into the trace buffer */
/* for the next trace entry. Index can wrap (ringbuffer) */
int XRayTraceNextEntry(struct XRayTraceCapture* capture, int index) {
if (XRayTraceIsAnnotation(capture, index))
index = XRayTraceSkipAnnotation(capture, index);
else
index = XRayTraceIncrementIndexInline(capture, index);
return index;
}
int XRayFrameGetTraceStartIndex(struct XRayTraceCapture* capture, int frame) {
assert(capture);
assert(capture->initialized);
assert(!capture->recording);
return capture->frame.entry[frame].start;
}
int XRayFrameGetTraceEndIndex(struct XRayTraceCapture* capture, int frame) {
assert(capture);
assert(capture->initialized);
assert(!capture->recording);
return capture->frame.entry[frame].end;
}
/* Not very accurate, annotation strings will also be counted as "entries" */
int XRayFrameGetTraceCount(
struct XRayTraceCapture* capture, int frame) {
assert(true == capture->initialized);
assert(frame >= 0);
assert(frame < capture->frame.count);
assert(!capture->recording);
int start = capture->frame.entry[frame].start;
int end = capture->frame.entry[frame].end;
int num;
if (start < end)
num = end - start;
else
num = capture->buffer_size - (start - end);
return num;
}
/* Append a string to trace buffer. */
void XRayTraceAppendString(struct XRayTraceCapture* capture, char* src) {
int index = capture->buffer_index;
bool done = false;
int start_index = 1;
int s = 0;
int i;
char* dst = (char*)&capture->buffer[index];
const int num = sizeof(capture->buffer[index]);
dst[0] = 0;
while (!done) {
for (i = start_index; i < num; ++i) {
dst[i] = src[s];
if (0 == src[s]) {
dst[i] = 0;
done = true;
break;
}
++s;
}
index = XRayTraceIncrementIndexInline(capture, index);
dst = (char*)&capture->buffer[index];
start_index = 0;
}
capture->buffer_index = index;
}
/* Copies annotation from trace buffer to output string. */
int XRayTraceCopyToString(
struct XRayTraceCapture* capture, int index, char* dst) {
assert(XRayTraceIsAnnotation(capture, index));
bool done = false;
int i;
int d = 0;
int start_index = 1;
while (!done) {
char* src = (char*) &capture->buffer[index];
const int num = sizeof(capture->buffer[index]);
for (i = start_index; i < num; ++i) {
dst[d] = src[i];
if (0 == src[i]) {
done = true;
break;
}
++d;
}
index = XRayTraceIncrementIndexInline(capture, index);
start_index = 0;
}
return index;
}
/* Generic memory malloc for XRay */
/* validates pointer returned by malloc */
/* memsets memory block to zero */
void* XRayMalloc(size_t t) {
void* data;
data = calloc(1, t);
if (NULL == data) {
printf("XRay: malloc(%d) failed, panic shutdown!\n", t);
exit(-1);
}
return data;
}
/* Generic memory free for XRay */
void XRayFree(void* data) {
assert(NULL != data);
free(data);
}
/* Main profile capture function that is called at the start */
/* of every instrumented function. This function is implicitly */
/* called when code is compilied with the -finstrument-functions option */
#if defined(__pnacl__)
void __pnacl_profile_func_enter(const char* this_fn) {
#else
void __cyg_profile_func_enter(void* this_fn, void* call_site) {
#endif
struct XRayTraceCapture* capture = g_xray_capture;
if (capture && capture->recording) {
uint32_t depth = capture->stack_depth;
if (depth < capture->max_stack_depth) {
struct XRayTraceStackEntry* se = &capture->stack[depth];
uint32_t addr = (uint32_t)(uintptr_t)this_fn;
se->depth_addr = XRAY_PACK_DEPTH_ADDR(depth, addr);
se->dest = capture->buffer_index;
se->annotation_index = 0;
GTSC(se->tsc);
capture->buffer_index =
XRayTraceIncrementIndexInline(capture, capture->buffer_index);
}
++capture->stack_depth;
}
}
/* Main profile capture function that is called at the exit of */
/* every instrumented function. This function is implicity called */
/* when the code is compiled with the -finstrument-functions option */
#if defined(__pnacl__)
void __pnacl_profile_func_exit(const char* this_fn) {
#else
void __cyg_profile_func_exit(void* this_fn, void* call_site) {
#endif
struct XRayTraceCapture* capture = g_xray_capture;
if (capture && capture->recording) {
--capture->stack_depth;
if (capture->stack_depth < capture->max_stack_depth) {
uint32_t depth = capture->stack_depth;
struct XRayTraceStackEntry* se = &capture->stack[depth];
uint32_t buffer_index = se->dest;
uint64_t tsc;
struct XRayTraceBufferEntry* be = &capture->buffer[buffer_index];
GTSC(tsc);
be->depth_addr = se->depth_addr;
be->start_tick = se->tsc;
be->end_tick = tsc;
be->annotation_index = 0;
if (0 != se->annotation_index)
__xray_profile_append_annotation(capture, se, be);
}
}
}
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
void XRayGetTSC(uint64_t* tsc) {
GTSC(*tsc);
}
int32_t XRayGetSavedThreadID(struct XRayTraceCapture* capture) {
return capture->thread_id;
}
struct XRayTimestampPair XRayFrameGetStartTimestampPair(
struct XRayTraceCapture* capture, int frame) {
return capture->frame.entry[frame].start_time;
}
struct XRayTimestampPair XRayFrameGetEndTimestampPair(
struct XRayTraceCapture* capture, int frame) {
return capture->frame.entry[frame].end_time;
}
#endif
/* Special case appending annotation string to trace buffer */
/* this function should only ever be called from __cyg_profile_func_exit() */
void __xray_profile_append_annotation(struct XRayTraceCapture* capture,
struct XRayTraceStackEntry* se,
struct XRayTraceBufferEntry* be) {
struct XRayTraceStackEntry* parent = se - 1;
int start = parent->annotation_index;
be->annotation_index = capture->buffer_index;
char* str = &capture->annotation[start];
XRayTraceAppendString(capture, str);
*str = 0;
++capture->annotation_count;
}
/* Annotates the trace buffer. no filtering. */
void __XRayAnnotate(const char* fmt, ...) {
va_list args;
struct XRayTraceCapture* capture = g_xray_capture;
/* Only annotate functions recorded in the trace buffer. */
if (capture && capture->initialized) {
if (0 == capture->disabled) {
if (capture->recording) {
char buffer[1024];
int r;
va_start(args, fmt);
r = vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
{
/* Get current string ptr */
int depth = capture->stack_depth - 1;
struct XRayTraceStackEntry* se = &capture->stack[depth];
if (0 == se->annotation_index) {
struct XRayTraceStackEntry* parent = se - 1;
se->annotation_index = parent->annotation_index;
}
char* dst = &capture->annotation[se->annotation_index];
strcpy(dst, buffer);
int len = strlen(dst);
se->annotation_index += len;
}
}
}
}
}
/* Annotates the trace buffer with user strings. Can be filtered. */
void __XRayAnnotateFiltered(const uint32_t filter, const char* fmt, ...) {
va_list args;
struct XRayTraceCapture* capture = g_xray_capture;
if (capture && capture->initialized) {
if (0 != (filter & capture->annotation_filter)) {
if (0 == capture->disabled) {
if (capture->recording) {
char buffer[XRAY_TRACE_ANNOTATION_LENGTH];
int r;
va_start(args, fmt);
r = vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
{
/* get current string ptr */
int depth = capture->stack_depth - 1;
struct XRayTraceStackEntry* se = &capture->stack[depth];
if (0 == se->annotation_index) {
struct XRayTraceStackEntry* parent = se - 1;
se->annotation_index = parent->annotation_index;
}
char* dst = &capture->annotation[se->annotation_index];
strcpy(dst, buffer);
int len = strlen(dst);
se->annotation_index += len;
}
}
}
}
}
}
/* Allows user to specify annotation filter value, a 32 bit mask. */
void XRaySetAnnotationFilter(struct XRayTraceCapture* capture,
uint32_t filter) {
capture->annotation_filter = filter;
}
/* Reset xray profiler. */
void XRayReset(struct XRayTraceCapture* capture) {
assert(capture);
assert(capture->initialized);
assert(!capture->recording);
capture->buffer_index = 0;
capture->stack_depth = 0;
capture->disabled = 0;
capture->frame.head = 0;
capture->frame.tail = 0;
memset(capture->frame.entry, 0,
sizeof(capture->frame.entry[0]) * capture->frame.count);
memset(&capture->stack, 0,
sizeof(capture->stack[0]) * XRAY_TRACE_STACK_SIZE);
XRayCheckGuards(capture);
}
/* Change the maximum stack depth captures are made. */
void XRaySetMaxStackDepth(struct XRayTraceCapture* capture, int stack_depth) {
assert(capture);
assert(capture->initialized);
assert(!capture->recording);
if (stack_depth < 1)
stack_depth = 1;
if (stack_depth >= XRAY_TRACE_STACK_SIZE)
stack_depth = (XRAY_TRACE_STACK_SIZE - 1);
capture->max_stack_depth = stack_depth;
}
int XRayFrameGetCount(struct XRayTraceCapture* capture) {
return capture->frame.count;
}
int XRayFrameGetTail(struct XRayTraceCapture* capture) {
return capture->frame.tail;
}
int XRayFrameGetHead(struct XRayTraceCapture* capture) {
return capture->frame.head;
}
int XRayFrameGetPrev(struct XRayTraceCapture* capture, int i) {
i = i - 1;
if (i < 0)
i = capture->frame.count - 1;
return i;
}
int XRayFrameGetNext(struct XRayTraceCapture* capture, int i) {
i = i + 1;
if (i >= capture->frame.count)
i = 0;
return i;
}
bool XRayFrameIsValid(struct XRayTraceCapture* capture, int i) {
return capture->frame.entry[i].valid;
}
uint64_t XRayFrameGetTotalTicks(struct XRayTraceCapture* capture, int i) {
return capture->frame.entry[i].total_ticks;
}
int XRayFrameGetAnnotationCount(struct XRayTraceCapture* capture, int i) {
return capture->frame.entry[i].annotation_count;
}
void XRayFrameMakeLabel(struct XRayTraceCapture* capture,
int counter,
char* label) {
if(counter < sizeof(capture->frame_labels) && capture->frame_labels[counter][0]) {
snprintf(label, XRAY_MAX_LABEL, "%s", capture->frame_labels[counter]);
} else {
snprintf(label, XRAY_MAX_LABEL, "frame_%i", counter);
}
}
void XRayLabelFrame(const char* fmt, ...)
{
char buffer[32];
int r;
va_list args;
va_start(args, fmt);
r = vsnprintf(buffer, sizeof(buffer), fmt, args);
if(r != 0) {
const int n = XRayFrameGetHead(g_xray_capture);
if(n < sizeof(g_xray_capture->frame_labels)) {
strcpy(g_xray_capture->frame_labels[n], buffer);
} else {
puts("XRay: Not enough entries in frame label buffer");
puts(" Add -DXRAY_FRAME_LBL_BUFSIZE=[n] to your CFLAGS");
}
}
va_end(args);
}
/* Scans the ring buffer going backwards to find last valid complete frame. */
/* Will mark whether frames are valid or invalid during the traversal. */
int XRayFrameFindTail(struct XRayTraceCapture* capture) {
int head = capture->frame.head;
int index = XRayFrameGetPrev(capture, head);
int total_capture = 0;
int last_valid_frame = index;
/* Check for no captures */
if (capture->frame.head == capture->frame.tail)
return capture->frame.head;
/* Go back and invalidate all captures that have been stomped. */
while (index != head) {
bool valid = capture->frame.entry[index].valid;
if (valid) {
total_capture += XRayFrameGetTraceCount(capture, index) + 1;
if (total_capture < capture->buffer_size) {
last_valid_frame = index;
capture->frame.entry[index].valid = true;
} else {
capture->frame.entry[index].valid = false;
}
}
index = XRayFrameGetPrev(capture, index);
}
return last_valid_frame;
}
/* Starts a new frame and enables capturing, and must be paired with */
/* XRayEndFrame() Trace capturing only occurs on the thread which called */
/* XRayBeginFrame() and each instance of capture can only trace one thread */
/* at a time. */
void XRayStartFrame(struct XRayTraceCapture* capture) {
int i;
assert(NULL == g_xray_capture);
assert(capture->initialized);
assert(!capture->recording);
i = capture->frame.head;
XRayCheckGuards(capture);
/* Add a trace entry marker so we can detect wrap around stomping */
struct XRayTraceBufferEntry* be = &capture->buffer[capture->buffer_index];
be->depth_addr = XRAY_FRAME_MARKER;
capture->buffer_index =
XRayTraceIncrementIndex(capture, capture->buffer_index);
/* Set start of the frame we're about to trace */
capture->frame.entry[i].start = capture->buffer_index;
capture->disabled = 0;
capture->stack_depth = 1;
/* The trace stack[0] is reserved */
memset(&capture->stack[0], 0, sizeof(capture->stack[0]));
/* Annotation index 0 is reserved to indicate no annotation */
capture->stack[0].annotation_index = 1;
capture->annotation[0] = 0;
capture->annotation[1] = 0;
capture->annotation_count = 0;
capture->recording = true;
GTSC(capture->frame.entry[i].start_tsc);
g_xray_capture = capture;
// initialize frame label
if(i < sizeof(capture->frame_labels)) {
capture->frame_labels[i][0] = 0;
}
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
capture->frame.entry[i].start_time = XRayGenerateTimestampsNow();
#endif
}
/* Ends a frame and disables capturing. Advances to the next frame. */
/* Must be paired with XRayStartFrame(), and called from the same thread. */
void XRayEndFrame(struct XRayTraceCapture* capture) {
int i;
assert(capture);
assert(capture->initialized);
assert(capture->recording);
assert(g_xray_capture == capture);
assert(0 == capture->disabled);
assert(1 == capture->stack_depth);
i = capture->frame.head;
GTSC(capture->frame.entry[i].end_tsc);
capture->frame.entry[i].total_ticks =
capture->frame.entry[i].end_tsc - capture->frame.entry[i].start_tsc;
capture->recording = NULL;
capture->frame.entry[i].end = capture->buffer_index;
capture->frame.entry[i].valid = true;
capture->frame.entry[i].annotation_count = capture->annotation_count;
capture->frame.head = XRayFrameGetNext(capture, capture->frame.head);
/* If the table is filled, bump the tail. */
if (capture->frame.head == capture->frame.tail)
capture->frame.tail = XRayFrameGetNext(capture, capture->frame.tail);
capture->frame.tail = XRayFrameFindTail(capture);
/* Check that we didn't stomp over trace entry marker. */
int marker = XRayTraceDecrementIndex(capture, capture->frame.entry[i].start);
struct XRayTraceBufferEntry* be = &capture->buffer[marker];
if (be->depth_addr != XRAY_FRAME_MARKER) {
fprintf(stderr,
"XRay: XRayStopFrame() detects insufficient trace buffer size!\n");
XRayReset(capture);
} else {
/* Replace marker with an empty annotation string. */
be->depth_addr = XRAY_NULL_ANNOTATION;
XRayCheckGuards(capture);
}
g_xray_capture = NULL;
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
capture->frame.entry[i].end_time = XRayGenerateTimestampsNow();
#endif
}
/* Get the last frame captured. Do not call while capturing. */
/* (ie call outside of XRayStartFrame() / XRayStopFrame() pair) */
int XRayGetLastFrame(struct XRayTraceCapture* capture) {
assert(capture);
assert(capture->initialized);
assert(!capture->recording);
assert(0 == capture->disabled);
assert(1 == capture->stack_depth);
int last_frame = XRayFrameGetPrev(capture, capture->frame.head);
return last_frame;
}
/* Disables capturing until a paired XRayEnableCapture() is called */
/* This call can be nested, but must be paired with an enable */
/* (If you need to just exclude a specific function and not its */
/* children, the XRAY_NO_INSTRUMENT modifier might be better) */
/* Must be called from same thread as XRayBeginFrame() / XRayEndFrame() */
void XRayDisableCapture(struct XRayTraceCapture* capture) {
assert(capture);
assert(capture == g_xray_capture);
assert(capture->initialized);
++capture->disabled;
capture->recording = false;
}
/* Re-enables capture. Must be paired with XRayDisableCapture() */
void XRayEnableCapture(struct XRayTraceCapture* capture) {
assert(capture);
assert(capture == g_xray_capture);
assert(capture->initialized);
assert(0 < capture->disabled);
--capture->disabled;
if (0 == capture->disabled) {
capture->recording = true;
}
}
struct XRaySymbolTable* XRayGetSymbolTable(struct XRayTraceCapture* capture) {
return capture->symbols;
}
/* Initialize XRay */
struct XRayTraceCapture* XRayInit(int stack_depth,
int buffer_size,
int frame_count,
const char* mapfilename) {
struct XRayTraceCapture* capture;
capture = (struct XRayTraceCapture*)XRayMalloc(
sizeof(struct XRayTraceCapture));
int adj_frame_count = frame_count + 1;
size_t buffer_size_in_bytes =
sizeof(capture->buffer[0]) * buffer_size;
size_t frame_size_in_bytes =
sizeof(capture->frame.entry[0]) * adj_frame_count;
capture->buffer =
(struct XRayTraceBufferEntry *)XRayMalloc(buffer_size_in_bytes);
capture->frame.entry =
(struct XRayTraceFrameEntry *)XRayMalloc(frame_size_in_bytes);
capture->buffer_size = buffer_size;
capture->frame.count = adj_frame_count;
capture->frame.head = 0;
capture->frame.tail = 0;
capture->disabled = 0;
capture->annotation_filter = 0xFFFFFFFF;
capture->guard0 = XRAY_GUARD_VALUE_0x12345678;
capture->guard1 = XRAY_GUARD_VALUE_0x12345678;
capture->guard2 = XRAY_GUARD_VALUE_0x87654321;
capture->guard3 = XRAY_GUARD_VALUE_0x12345678;
capture->initialized = true;
capture->recording = false;
XRaySetMaxStackDepth(capture, stack_depth);
XRayReset(capture);
/* Mapfile is optional; we don't need it for captures, only for reports. */
capture->symbols =
XRaySymbolTableCreate(XRAY_DEFAULT_SYMBOL_TABLE_SIZE);
if (NULL != mapfilename)
XRaySymbolTableParseMapfile(capture->symbols, mapfilename);
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
/* Use the address of a thread local variable as a fake thread id. */
capture->thread_id = (int32_t)(&g_xray_thread_id_placeholder);
#endif
return capture;
}
/* Shut down and free memory used by XRay. */
void XRayShutdown(struct XRayTraceCapture* capture) {
assert(capture);
assert(capture->initialized);
assert(!capture->recording);
XRayCheckGuards(capture);
if (NULL != capture->symbols) {
XRaySymbolTableFree(capture->symbols);
}
XRayFree(capture->frame.entry);
XRayFree(capture->buffer);
capture->initialized = false;
XRayFree(capture);
}
#endif /* XRAY */

125
hermit/usr/xray/xray.h Normal file
View file

@ -0,0 +1,125 @@
/* 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 LIBRARIES_XRAY_XRAY_H_
#define LIBRARIES_XRAY_XRAY_H_
#include <stdint.h>
// we don't want that
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
#define XRAY_DISABLE_BROWSER_INTEGRATION
#endif
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
#include "ppapi/c/ppb.h"
#endif
#if defined(__arm__)
#undef XRAY
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define XRAY_NO_INSTRUMENT __attribute__((no_instrument_function))
#define XRAY_INLINE __attribute__((always_inline, no_instrument_function))
#if defined(XRAY)
/* Do not call __XRayAnnotate* directly; instead use the */
/* XRayAnnotate() macros below. */
XRAY_NO_INSTRUMENT void __XRayAnnotate(const char* str, ...)
__attribute__ ((format(printf, 1, 2)));
XRAY_NO_INSTRUMENT void __XRayAnnotateFiltered(const uint32_t filter,
const char* str, ...) __attribute__ ((format(printf, 2, 3)));
/* This is the beginning of the public XRay API */
/* Ok if mapfilename is NULL, no symbols will be loaded. On glibc builds,
* XRay will also attempt to populate the symbol table with dladdr()
*/
XRAY_NO_INSTRUMENT struct XRayTraceCapture* XRayInit(int stack_size,
int buffer_size,
int frame_count,
const char* mapfilename);
XRAY_NO_INSTRUMENT void XRayShutdown(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayStartFrame(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayEndFrame(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayLabelFrame(const char* fmt, ...);
XRAY_NO_INSTRUMENT void XRaySetAnnotationFilter(
struct XRayTraceCapture* capture, uint32_t filter);
XRAY_NO_INSTRUMENT void XRaySaveReport(struct XRayTraceCapture* capture,
const char* filename,
float percent_cutoff,
int cycle_cutoff);
XRAY_NO_INSTRUMENT void XRayReport(struct XRayTraceCapture* capture,
FILE* f,
float percent_cutoff,
int ticks_cutoff);
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
XRAY_NO_INSTRUMENT void XRayBrowserTraceReport(
struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayRegisterBrowserInterface(
PPB_GetInterface get_browser_interface);
#endif /* XRAY_DISABLE_BROWSER_INTEGRATION */
#if defined(XRAY_ANNOTATE)
#define XRayAnnotate(...) __XRayAnnotate(__VA_ARGS__)
#define XRayAnnotateFiltered(...) __XRayAnnotateFiltered(__VA_ARGS__)
#else
#define XRayAnnotate(...)
#define XRayAnnotateFiltered(...)
#endif
/* This is the end of the public XRay API */
#else /* defined(XRAY) */
/* Builds that don't define XRAY will use these 'null' functions instead. */
#define XRayAnnotate(...)
#define XRayAnnotateFiltered(...)
inline struct XRayTraceCapture* XRayInit(int stack_size,
int buffer_size,
int frame_count,
const char* mapfilename) {
return NULL;
}
inline void XRayShutdown(struct XRayTraceCapture* capture) {}
inline void XRayStartFrame(struct XRayTraceCapture* capture) {}
inline void XRayEndFrame(struct XRayTraceCapture* capture) {}
inline void XRayLabelFrame(const char* fmt, ...) {}
inline void XRaySetAnnotationFilter(struct XRayTraceCapture* capture,
uint32_t filter) {}
inline void XRaySaveReport(struct XRayTraceCapture* capture,
const char* filename,
float percent_cutoff,
int cycle_cutoff) {}
inline void XRayReport(struct XRayTraceCapture* capture,
FILE* f,
float percent_cutoff,
int ticks_cutoff) {}
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
inline void XRayBrowserTraceReport(struct XRayTraceCapture* capture) {}
inline void XRayRegisterBrowserInterface(
PPB_GetInterface get_browser_interface) {}
#endif /* XRAY_DISABLE_BROWSER_INTEGRATION */
#endif /* defined(XRAY) */
#ifdef __cplusplus
}
#endif
#endif /* LIBRARIES_XRAY_XRAY_H_ */

BIN
hermit/usr/xray/xray.odt Normal file

Binary file not shown.

210
hermit/usr/xray/xray_priv.h Normal file
View file

@ -0,0 +1,210 @@
/* 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 */
/* This header file is the private internal interface. */
#ifndef LIBRARIES_XRAY_XRAY_PRIV_H_
#define LIBRARIES_XRAY_XRAY_PRIV_H_
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "xray.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(XRAY)
#define XRAY_FORCE_INLINE __attribute__((always_inline, no_instrument_function))
#define XRAY_TRACE_STACK_SIZE (256)
#define XRAY_TRACE_ANNOTATION_LENGTH (2048)
#define XRAY_TRACE_BUFFER_SIZE (1048576)
#define XRAY_ANNOTATION_STACK_SIZE ((XRAY_TRACE_STACK_SIZE) * \
(XRAY_TRACE_ANNOTATION_LENGTH))
#define XRAY_STRING_POOL_NODE_SIZE (32768)
#define XRAY_FRAME_MARKER (0xFFFFFFFF)
#define XRAY_NULL_ANNOTATION (0x0)
#define XRAY_FUNCTION_ALIGNMENT_BITS (4)
#define XRAY_ADDR_MASK (0xFFFFFF00)
#define XRAY_ADDR_SHIFT (4)
#define XRAY_DEPTH_MASK (0x000000FF)
#define XRAY_SYMBOL_TABLE_MAX_RATIO (0.66f)
#define XRAY_LINE_SIZE (1024)
#define XRAY_MAX_FRAMES (60)
#define XRAY_MAX_LABEL (32)
#define XRAY_DEFAULT_SYMBOL_TABLE_SIZE (4096)
#define XRAY_SYMBOL_POOL_NODE_SIZE (1024)
#define XRAY_GUARD_VALUE_0x12345678 (0x12345678)
#define XRAY_GUARD_VALUE_0x87654321 (0x87654321)
#define XRAY_EXTRACT_ADDR(x) (((x) & XRAY_ADDR_MASK) >> XRAY_ADDR_SHIFT)
#define XRAY_EXTRACT_DEPTH(x) ((x) & XRAY_DEPTH_MASK)
#define XRAY_PACK_ADDR(x) (((x) << XRAY_ADDR_SHIFT) & XRAY_ADDR_MASK)
#define XRAY_PACK_DEPTH(x) ((x) & XRAY_DEPTH_MASK)
#define XRAY_PACK_DEPTH_ADDR(d, a) (XRAY_PACK_DEPTH(d) | XRAY_PACK_ADDR(a))
#define XRAY_ALIGN64 __attribute((aligned(64)))
struct XRayStringPool;
struct XRayHashTable;
struct XRaySymbolPool;
struct XRaySymbol;
struct XRaySymbolTable;
struct XRayTraceCapture;
struct XRayTraceBufferEntry {
uint32_t depth_addr;
uint32_t annotation_index;
uint64_t start_tick;
uint64_t end_tick;
};
/* Important: don't instrument xray itself, so use */
/* XRAY_NO_INSTRUMENT on all xray functions */
XRAY_NO_INSTRUMENT char* XRayStringPoolAppend(struct XRayStringPool* pool,
const char* src);
XRAY_NO_INSTRUMENT struct XRayStringPool* XRayStringPoolCreate();
XRAY_NO_INSTRUMENT void XRayStringPoolFree(struct XRayStringPool* pool);
XRAY_NO_INSTRUMENT void* XRayHashTableLookup(struct XRayHashTable* table,
uint32_t addr);
XRAY_NO_INSTRUMENT void* XRayHashTableInsert(struct XRayHashTable* table,
void* data, uint32_t addr);
XRAY_NO_INSTRUMENT void* XRayHashTableAtIndex(
struct XRayHashTable* table, int i);
XRAY_NO_INSTRUMENT int XRayHashTableGetCapacity(struct XRayHashTable* table);
XRAY_NO_INSTRUMENT int XRayHashTableGetCount(struct XRayHashTable* table);
XRAY_NO_INSTRUMENT struct XRayHashTable* XRayHashTableCreate(int capacity);
XRAY_NO_INSTRUMENT void XRayHashTableFree(struct XRayHashTable* table);
XRAY_NO_INSTRUMENT void XRayHashTableHisto(FILE* f);
XRAY_NO_INSTRUMENT struct XRaySymbol* XRaySymbolPoolAlloc(
struct XRaySymbolPool* sympool);
XRAY_NO_INSTRUMENT struct XRaySymbolPool* XRaySymbolPoolCreate();
XRAY_NO_INSTRUMENT void XRaySymbolPoolFree(struct XRaySymbolPool* sympool);
XRAY_NO_INSTRUMENT const char* XRayDemangle(char* demangle, size_t buffersize,
const char* symbol);
XRAY_NO_INSTRUMENT const char* XRaySymbolGetName(struct XRaySymbol* symbol);
XRAY_NO_INSTRUMENT struct XRaySymbol* XRaySymbolCreate(
struct XRaySymbolPool* sympool, const char* name);
XRAY_NO_INSTRUMENT void XRaySymbolFree(struct XRaySymbol* symbol);
XRAY_NO_INSTRUMENT int XRaySymbolCount(struct XRaySymbolTable* symtab);
XRAY_NO_INSTRUMENT struct XRaySymbol* XRaySymbolTableCreateEntry(
struct XRaySymbolTable* symtab, char* line);
XRAY_NO_INSTRUMENT void XRaySymbolTableParseMapfile(
struct XRaySymbolTable* symbols, const char* mapfilename);
XRAY_NO_INSTRUMENT struct XRaySymbol* XRaySymbolTableAddByName(
struct XRaySymbolTable* symtab, const char* name, uint32_t addr);
XRAY_NO_INSTRUMENT int XRaySymbolTableGetCount(struct XRaySymbolTable* symtab);
XRAY_NO_INSTRUMENT struct XRaySymbol* XRaySymbolTableLookup(
struct XRaySymbolTable* symbols, uint32_t addr);
XRAY_NO_INSTRUMENT struct XRaySymbol* XRaySymbolTableAtIndex(
struct XRaySymbolTable* symbols, int i);
XRAY_NO_INSTRUMENT struct XRaySymbolTable* XRaySymbolTableCreate(int size);
XRAY_NO_INSTRUMENT void XRaySymbolTableFree(struct XRaySymbolTable* symbtab);
XRAY_NO_INSTRUMENT struct XRaySymbolTable* XRayGetSymbolTable(
struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayCheckGuards(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT struct XRayTraceBufferEntry* XRayTraceGetEntry(
struct XRayTraceCapture* capture, int index);
XRAY_NO_INSTRUMENT int XRayTraceIncrementIndex(
struct XRayTraceCapture* capture, int i);
XRAY_NO_INSTRUMENT int XRayTraceDecrementIndex(
struct XRayTraceCapture* capture, int i);
XRAY_NO_INSTRUMENT bool XRayTraceIsAnnotation(
struct XRayTraceCapture* capture, int index);
XRAY_NO_INSTRUMENT void XRayTraceAppendString(
struct XRayTraceCapture* capture, char* src);
XRAY_NO_INSTRUMENT int XRayTraceCopyToString(
struct XRayTraceCapture* capture, int index, char* dst);
XRAY_NO_INSTRUMENT int XRayTraceSkipAnnotation(
struct XRayTraceCapture* capture, int index);
XRAY_NO_INSTRUMENT int XRayTraceNextEntry(
struct XRayTraceCapture* capture, int index);
XRAY_NO_INSTRUMENT void XRayFrameMakeLabel(struct XRayTraceCapture* capture,
int counter,
char* label);
XRAY_NO_INSTRUMENT int XRayFrameFindTail(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT int XRayFrameGetCount(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT int XRayFrameGetHead(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT int XRayFrameGetTail(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT int XRayFrameGetNext(
struct XRayTraceCapture* capture, int index);
XRAY_NO_INSTRUMENT uint64_t XRayFrameGetTotalTicks(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT int XRayFrameGetTraceCount(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT int XRayFrameGetTraceStartIndex(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT int XRayFrameGetTraceEndIndex(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT int XRayFrameGetAnnotationCount(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT bool XRayFrameIsValid(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT void XRayTraceReport(struct XRayTraceCapture* capture,
FILE* f,
int frame,
char* label,
float percent_cutoff,
int ticks_cutoff);
XRAY_NO_INSTRUMENT void XRayFrameReport(struct XRayTraceCapture* capture,
FILE* f);
XRAY_NO_INSTRUMENT void* XRayMalloc(size_t t);
XRAY_NO_INSTRUMENT void XRayFree(void* data);
XRAY_NO_INSTRUMENT void XRaySetMaxStackDepth(
struct XRayTraceCapture* capture, int stack_depth);
XRAY_NO_INSTRUMENT int XRayGetLastFrame(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayDisableCapture(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayEnableCapture(struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT void XRayLoadMapfile(
struct XRayTraceCapture* capture, const char* mapfilename);
struct XRayTimestampPair {
uint64_t xray; /* internal xray timestamp */
int64_t pepper; /* corresponding timestamp from PPAPI interface */
};
#ifndef XRAY_DISABLE_BROWSER_INTEGRATION
XRAY_NO_INSTRUMENT void XRayGetTSC(uint64_t* tsc);
XRAY_NO_INSTRUMENT int32_t XRayGetSavedThreadID(
struct XRayTraceCapture* capture);
XRAY_NO_INSTRUMENT struct XRayTimestampPair XRayFrameGetStartTimestampPair(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT struct XRayTimestampPair XRayFrameGetEndTimestampPair(
struct XRayTraceCapture* capture, int frame);
XRAY_NO_INSTRUMENT struct XRayTimestampPair XRayGenerateTimestampsNow(void);
#endif
#ifndef XRAY_FRAME_LBL_BUFSIZE
#define XRAY_FRAME_LBL_BUFSIZE 16
#endif
#endif /* defined(XRAY) */
#ifdef __cplusplus
}
#endif
#endif /* LIBRARIES_XRAY_XRAY_PRIV_H_ */