Devel-FastProf
view release on metacpan or search on metacpan
FastProf.xs view on Meta::CPAN
AV *lines = get_file_src(aTHX_ fn);
if (lines) {
putmark(2);
putiv(aTHX_ file_id_generator);
putav(aTHX_ lines);
}
}
return file_id_generator;
}
static IV
mapid(pTHX_ HV *fpidmap, IV pid, IV fid) {
static IV lfpid = 0;
static SV *key = 0;
SV **ent;
char *k;
STRLEN l;
if (!key) key = newSV(30);
sv_setpvf(key, "%d:%d", pid, fid);
k = SvPV(key, l);
ent = hv_fetch(fpidmap, k, l, TRUE);
if (!SvOK(*ent))
sv_setiv(*ent, ++lfpid);
return SvIV(*ent);
}
static void
flock_and_header(pTHX) {
static IV lpid = 0;
IV pid = getpid();
if (pid != lpid && lpid) {
out = fopen(outname, "ab");
if (!out)
Perl_croak(aTHX_ "unable to reopen file %s", outname);
flock(fileno(out), LOCK_EX);
fseek(out, 0, SEEK_END);
putmark(5);
putiv(aTHX_ pid);
putmark(6);
putiv(aTHX_ lpid);
}
else {
flock(fileno(out), LOCK_EX);
fseek(out, 0, SEEK_END);
putmark(5);
putiv(aTHX_ pid);
}
lpid = pid;
}
MODULE = Devel::FastProf PACKAGE = DB
PROTOTYPES: DISABLE
void DB(...)
PPCODE:
{
IV ticks;
if (usecputime) {
struct tms buf;
times(&buf);
ticks = buf.tms_utime - old_tms.tms_utime + buf.tms_stime - old_tms.tms_stime;
}
else {
#if defined(HAS_GETTIMEOD)
struct timeval time;
gettimeofday(&time, NULL);
if (time.tv_sec < old_time.tv_sec + 2000) {
ticks = (time.tv_sec - old_time.tv_sec) * 1000000 + time.tv_usec - old_time.tv_usec;
}
#else
UV time[2];
(*u2time)(aTHX_ time);
if (time[0] < old_time[0] + 2000) {
ticks = (time[0] - old_time[0]) * 1000000 + time[1] - old_time[1];
}
#endif
else {
ticks = 2000000000;
}
}
if (out) { /* out should never be NULL anyway */
IV fid;
IV line;
char *file;
#if (PERL_VERSION < 8) || ((PERL_VERSION == 8) && (PERL_SUBVERSION < 8))
PERL_CONTEXT *cx = cxstack + cxstack_ix;
#endif
if (canfork)
flock_and_header(aTHX);
#if (PERL_VERSION < 8) || ((PERL_VERSION == 8) && (PERL_SUBVERSION < 8))
file = OutCopFILE(cx->blk_oldcop);
line = CopLINE(cx->blk_oldcop);
#else
file = OutCopFILE(PL_curcop);
line = CopLINE(PL_curcop);
#endif
if (strcmp(file, old_fn)) {
fid = get_file_id(aTHX_ file);
putmark(7);
putiv(aTHX_ fid);
old_fn = file;
}
putiv(aTHX_ line);
if (ticks < 0) ticks = 0;
putiv(aTHX_ ticks);
if (canfork) {
fflush(out);
flock(fileno(out), LOCK_UN);
}
}
if (usecputime) {
times(&old_tms);
}
else {
#if defined (HAS_GETTIMEOD)
gettimeofday(&old_time, NULL);
#else
(*u2time)(aTHX_ old_time);
#endif
}
}
void _finish()
PPCODE:
{
if (out) {
if (canfork) {
flock_and_header(aTHX);
fflush(out);
flock(fileno(out), LOCK_UN);
}
fclose(out);
out = NULL;
}
}
void _init(char *_outname, int _usecputime, int _canfork)
PPCODE:
{
out = fopen(_outname, "wb");
if (!out) Perl_croak(aTHX_ "unable to open file %s for writing", _outname);
fwrite("D::FP-" XS_VERSION "\0\0\0\0\0\0\0", 1, 12, out);
putmark(3);
if (_usecputime) {
usecputime = 1;
putiv(aTHX_ sysconf(_SC_CLK_TCK));
times(&old_tms);
}
else {
putiv(aTHX_ 1000000);
usecputime = 0;
#if defined (HAS_GETTIMEOD)
gettimeofday(&old_time, NULL);
#else
{
SV **svp = hv_fetch(PL_modglobal, "Time::U2time", 12, 0);
if (!svp || !SvIOK(*svp)) Perl_croak(aTHX_ "Time::HiRes is required");
u2time = INT2PTR(int(*)(pTHX_ UV*), SvIV(*svp));
}
(*u2time)(aTHX_ old_time);
#endif
}
if (_canfork) {
canfork = 1;
outname = strdup(_outname);
}
file_id_hv = get_hv("DB::file_id", TRUE);
}
MODULE = Devel::FastProf PACKAGE = Devel::FastProf::Reader
void _read_file(char *infn)
PPCODE:
{
HV *ticks = get_hv("Devel::FastProf::Reader::TICKS", TRUE);
HV *count = get_hv("Devel::FastProf::Reader::COUNT", TRUE);
AV *fn = get_av("Devel::FastProf::Reader::FN", TRUE);
AV *src = get_av("Devel::FastProf::Reader::SRC", TRUE);
HV *fpidmap = get_hv("Devel::FastProf::Reader::FPIDMAP", TRUE);
HV *ppid = get_hv("Devel::FastProf::Reader::PPID", TRUE);
float inv_ticks_per_second = 1.0;
IV lfid = 0, nfid = 0, lline;
int not_first = 0;
IV pid = 0;
SV *key = sv_2mortal(newSV(30));
char *k;
STRLEN l;
SV **ent;
char head[12];
HV *pidlfid = (HV*)sv_2mortal((SV*)newHV());
HV *pidlline = (HV*)sv_2mortal((SV*)newHV());
FILE *in = fopen(infn, "rb");
if (!in) Perl_croak(aTHX_ "unable to open %s for reading", infn);
if ((fread(head, 1, 12, in) != 12) || strncmp(head, "D::FP-" XS_VERSION, 12))
Perl_croak(aTHX_ "bad header, input file has not been generated by Devel::FastProf " XS_VERSION);
while (fneof(in)) {
IV mark = fgetmark(aTHX_ in);
switch (mark) {
case 0: /* line execution timestamp */
{
IV line = fgetiv(aTHX_ in);
IV delta = fgetiv(aTHX_ in);
/* fprintf(stderr, "fid: %d, line: %d, delta: %d\n", fid, line, delta); */
if (not_first) {
SV **tsv, **csv;
/* SV *key = newSVpvf("%d:%d", lfid, lline); */
sv_setpvf(key, "%d:%d", lfid, lline);
k = SvPV(key, l);
tsv = hv_fetch(ticks, k, l, TRUE);
csv = hv_fetch(count, k, l, TRUE);
if (tsv && csv) {
float old = SvOK(*tsv) ? SvNV(*tsv) : 0.0;
/* printf("delta: %d\n", delta); */
sv_setnv(*tsv, old + delta * inv_ticks_per_second);
sv_inc(*csv);
}
else {
Perl_croak(aTHX_ "internal error");
}
}
else {
not_first = 1;
}
lfid = nfid;
lline = line;
break;
}
case 1: /* filename comming */
{
IV fid = pid ? mapid(aTHX_ fpidmap, pid, fgetiv(aTHX_ in)) : fgetiv(aTHX_ in);
( run in 1.939 second using v1.01-cache-2.11-cpan-71847e10f99 )