#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#ifndef USE_ITHREADS
int count_down;
int inside_logger;
int log_size;
#endif
void
take_snapshot(pTHX)
{
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
call_pv("Devel::ContinuousProfiler::take_snapshot",G_DISCARD|G_NOARGS);
FREETMPS;
LEAVE;
}
int
sp_runops(pTHX)
{
dVAR;
#ifdef USE_ITHREADS
SV * count_down_sv, *inside_logger_sv, *log_size_sv;
register OP *op = PL_op;
while ((PL_op = op = CALL_FPTR(op->op_ppaddr)(aTHX))) {
count_down_sv = get_sv("Devel::ContinuousProfiler::count_down", 0);
assert(count_down_sv);
assert(SvIV(count_down_sv) >= 0);
if (SvTRUE(count_down_sv)) {
sv_dec(count_down_sv);
}
else {
inside_logger_sv = get_sv("Devel::ContinuousProfiler::inside_logger", 0);
assert(inside_logger_sv);
assert(SvIV(inside_logger_sv) == 1
|| SvIV(inside_logger_sv) == 0);
log_size_sv = get_sv("Devel::ContinuousProfiler::log_size", GV_ADD);
assert(log_size_sv);
if (SvTRUE(inside_logger_sv)) {
sv_inc(log_size_sv);
}
else {
sv_setiv(inside_logger_sv, 1);
sv_setiv(log_size_sv, 0);
take_snapshot(aTHX);
sv_setiv(
count_down_sv,
SvIV(log_size_sv) > 1024
? (SvIV(log_size_sv) << 10)
: (1024 << 10));
sv_setiv(inside_logger_sv, 0);
}
}
}
#else
register OP *op = PL_op;
while ((PL_op = op = CALL_FPTR(op->op_ppaddr)(aTHX))) {
if ( count_down > 0 ) {
-- count_down;
}
else {
if ( inside_logger ) {
++ log_size;
}
else {
inside_logger = 1;
log_size = 0;
take_snapshot(aTHX);
count_down =
log_size > 1024
? (log_size << 10)
: (1024 << 10);
inside_logger = 0;
}
}
}
#endif
TAINT_NOT;
return 0;
}
void
_initialize()
{
#ifdef USE_ITHREADS
sv_setiv(get_sv("Devel::ContinuousProfiler::count_down", GV_ADD), 0);
sv_setiv(get_sv("Devel::ContinuousProfiler::inside_logger", GV_ADD), 0);
sv_setiv(get_sv("Devel::ContinuousProfiler::log_size", GV_ADD), 1024 < 10);
#endif
PL_runops = sp_runops;
}
MODULE = Devel::ContinuousProfiler PACKAGE = Devel::ContinuousProfiler
PROTOTYPES: DISABLE
void
_initialize()
BOOT:
_initialize();