mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

129 lines
2.3 KiB

/* Bash (wallclock-time) profiler. Written by Clifford Wolf.
*
* Usage:
* gcc -shared -fPIC -Wall -o bash_profiler.so bash_profiler.c
* enable -f ./bash_profiler.so bprof
*
* bprof a start; idle_in_a; brof a stop
* bprof b start; idle_in_b; brof b stop
* bprof a start; idle_in_a; brof a stop
*
* bprof all print
* enable -d bprof
*/
/* Some declarations copied from bash-2.05b headers */
#include <stdint.h>
typedef struct word_desc {
char *word;
int flags;
} WORD_DESC;
typedef struct word_list {
struct word_list *next;
WORD_DESC *word;
} WORD_LIST;
typedef int sh_builtin_func_t(WORD_LIST *);
#define BUILTIN_ENABLED 0x1
struct builtin {
char *name;
sh_builtin_func_t *function;
int flags;
char * const *long_doc;
const char *short_doc;
char *handle;
};
/* my hellobash builtin */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
long long mytime()
{
struct timeval tv;
gettimeofday(&tv, 0);
return tv.tv_sec*1000 + tv.tv_usec/1000;
}
struct bprofent;
struct bprofent {
char *id;
int count;
long long tv_sum, tv_start;
struct bprofent *next;
};
struct bprofent *bprofent_list = 0;
int bprof_builtin(WORD_LIST *list)
{
struct bprofent *this = bprofent_list;
char *mode, *name;
if ( !list || !list->next ) {
fprintf(stderr, "Usage: bprof {id|all} {start|stop|print}\n");
return 1;
}
name = list->word->word;
mode = list->next->word->word;
if ( !strcmp(mode, "print") && !strcmp(name, "all") ) {
while ( this ) {
printf("%7d %7Ld %10.3f %s\n", this->count, this->tv_sum,
(float)this->tv_sum/this->count, this->id);
this = this->next;
}
return 0;
}
while ( this ) {
if ( !strcmp(this->id, name) ) break;
this = this->next;
}
if ( !this ) {
this = calloc(1, sizeof(struct bprofent));
this->id = strdup(name);
this->next = bprofent_list;
bprofent_list = this;
}
if ( !strcmp(mode, "start") ) {
this->tv_start = mytime();
} else if ( !strcmp(mode, "stop") ) {
this->tv_sum += mytime() - this->tv_start;
this->count++;
} else if ( !strcmp(mode, "print") ) {
printf("%7d %7Ld %10.3f %s\n", this->count, this->tv_sum,
(float)this->tv_sum/this->count, this->id);
}
return 0;
}
char *bprof_doc[] = {
"bash profiler",
0
};
struct builtin bprof_struct = {
"bprof",
&bprof_builtin,
BUILTIN_ENABLED,
bprof_doc,
"bash profiler",
0
};