lib/cds/simple_profile.c
d3ff177a
 #include <stdio.h>
 #include <cds/simple_profile.h>
 #include <signal.h>
 #include <sys/time.h>
 #include <string.h>
 
 /* FIXME: only for testing */
 /*#include "dprint.h"*/
 
 #define trace_signal SIGTRAP
 
115c1a72
 typedef void (*_sig_t) (int);
 
d3ff177a
 unsigned int tick_counter = 0;
 static struct sigaction old_sigprof_action;
cd2fbac5
 static _sig_t old_sigx_action;
d3ff177a
 static int initialized = 0;
 static trace_f trace_function = NULL;
 
 int reset_timer()
 {
 	struct itimerval tv;
 	int res;
 	
 	tv.it_interval.tv_sec = 0;
 	tv.it_interval.tv_usec = 1000; 
 	/*tv.it_interval.tv_usec = 10 * 1000; */
 	tv.it_value.tv_sec = tv.it_interval.tv_sec;
 	tv.it_value.tv_usec = tv.it_interval.tv_usec;
 
 	res = setitimer(ITIMER_PROF, &tv, NULL);
 
 	return res;
 }
 
 void prof_handler(int a, siginfo_t *info, void *b)
 {
 	tick_counter++;
 /*	LOG(L_ERR, "PROFILE HANDLER called\n"); */
 	/* reset_timer(); */
 }
 
 void trace_handler(int a)
 {
 	if (trace_function) trace_function();
 }
 
 int start_profile(trace_f tf)
 {
 	struct sigaction action;
 	int res;
 
 	if (initialized) return 1;
 	initialized = 1;
 	trace_function = tf;
 
 	memset(&action, 0, sizeof(action));
 	action.sa_sigaction = prof_handler;
     sigemptyset(&action.sa_mask);
 	action.sa_flags = SA_SIGINFO;
 	res = sigaction(SIGPROF, &action, &old_sigprof_action);
 	if (res != 0) {
 		/* ERROR_LOG("can't set signal handle (%d)\n", res);*/
 		return -1;
 	}
 	
 	old_sigx_action = signal(trace_signal, &trace_handler);
 
 	res = reset_timer();
 	if (res != 0) {
 		/* ERROR_LOG("can't set itimer (%d)\n", res);*/
 		signal(trace_signal, old_sigx_action);
 		sigaction(SIGPROF, &old_sigprof_action, NULL);
 		return -1;
 	}
 
 	return 0;
 }
 
 int stop_profile()
 {
 	if (initialized) {
 		initialized = 0;
 		signal(trace_signal, old_sigx_action);
 		return sigaction(SIGPROF, &old_sigprof_action, NULL);
 	}
 	else return -1;
 }