2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Chang Bae <c.s.bae@u.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
22 #include <palacios/svm_handler.h>
23 #include <palacios/vmm_instrument.h>
25 #define NO_INSTRUMENTATION
26 #include <palacios/vmm_ringbuffer.h>
27 #undef NO_INSTRUMENTATION
29 #define RING_SIZE 2000
31 static ullong_t last = 0;
32 static struct v3_ringbuf * func_ring = NULL;
34 struct instrumented_func {
39 } __attribute__((packed));
43 static void print_instrumentation() __attribute__((__no_instrument_function__));
45 void __cyg_profile_func_enter(void * this, void * callsite) __attribute__((__no_instrument_function__));
46 void __cyg_profile_func_exit(void * this, void * callsite) __attribute__((__no_instrument_function__));
48 void v3_init_instrumentation() {
49 PrintDebug("Creating Ring Buffer (unit size = %d)\n", (uint_t)sizeof(struct instrumented_func));
51 func_ring = v3_create_ringbuf(sizeof(struct instrumented_func) * RING_SIZE); //dequeue at every 4095
56 __attribute__((__no_instrument_function__))
57 void __cyg_profile_func_enter(void * this, void * callsite) {
59 if (func_ring != NULL) {
61 struct instrumented_func tmp_fn;
66 //PrintDebug("Entering Function\n");
68 if (v3_ringbuf_avail_space(func_ring) < sizeof(struct instrumented_func)) {
69 print_instrumentation();
72 tmp_fn.time = now - last; // current tsc
73 tmp_fn.exiting = 0; //enter to be 0
74 tmp_fn.called_fn = this; //this
75 tmp_fn.calling_fn = callsite; //callsite
77 // PrintDebug("Writing Function: fn_data=%p, size=%d\n",
78 // (void *)&tmp_fn, (uint_t)sizeof(struct instrumented_func));
79 v3_ringbuf_write(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
86 __attribute__((__no_instrument_function__))
87 void __cyg_profile_func_exit(void * this, void * callsite){
89 if (func_ring != NULL) {
91 struct instrumented_func tmp_fn;
96 // PrintDebug("Exiting Function\n");
98 if (v3_ringbuf_avail_space(func_ring) < sizeof(struct instrumented_func)) {
99 print_instrumentation();
102 tmp_fn.time = now - last; // current tsc
103 tmp_fn.exiting = 1; //exit to be 0
104 tmp_fn.called_fn = this; //this
105 tmp_fn.calling_fn = callsite; //callsite
107 // PrintDebug("Writing Function: fn_data=%p, size=%d\n",
108 // (void *)&tmp_fn, (uint_t)sizeof(struct instrumented_func));
109 v3_ringbuf_write(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
117 static void print_instrumentation() {
119 struct instrumented_func tmp_fn;
121 // PrintDebug("Printing Instrumentation\n");
122 while (v3_ringbuf_data_len(func_ring) >= sizeof(struct instrumented_func)) {
124 v3_ringbuf_read(func_ring, (uchar_t *)&tmp_fn, sizeof(struct instrumented_func));
126 PrintDebug("CYG_PROF: %d %p %p %p\n",
128 (void *)(addr_t)(tmp_fn.time),