Event-Stats

 view release on metacpan or  search on metacpan

lib/Event/Stats.xs  view on Meta::CPAN

{ safefree(stats); }

static pe_event_stats_vtbl Myvtbl =
  { 0, pe_enter, pe_suspend, pe_resume, pe_commit, pe_abort, pe_dtor };

static int Stats;
static void use_stats(int yes)
{
    int prev = Stats;
    Stats += yes;
    if (Stats < 0)
	Stats=0;
    if (!(!prev ^ !Stats))
	return;
    if (Stats) {
	pe_watcher *ev;
	/*    warn("reinit stats"); /**/
	ev = GEventAPI->AllWatchers->next->self;
	while (ev) {
	    if (ev->stats)
		pe_stat_init(ev->stats);
	    ev = ev->all.next->self;
	}
	pe_stat_init(&idleStats);
	pe_stat_init(&totalStats);
  
	if (!RollTimer)
	    RollTimer = GEventAPI->new_timer(0,0);
	RollTimer->interval = newSVnv(PE_STAT_SECONDS);
	ev = (pe_watcher*) RollTimer;
	WaREPEAT_on(ev);
	sv_setpv(ev->desc, "Event::Stats");
	ev->prio = PE_PRIO_NORMAL - 1;
	ev->callback = (void*) pe_stat_roll_cb;
	gettimeofday(&total_tm, 0);
	/* pretend we are repeating so 'at' can be uninitialized */
	GEventAPI->start(ev, 1);
	GEventAPI->collect_stats(1);
    } else {
	GEventAPI->stop((pe_watcher*) RollTimer, 1);
	GEventAPI->collect_stats(0);
    }
}

MODULE = Event::Stats		PACKAGE = Event::Stats

PROTOTYPES: DISABLE

BOOT:
     {
	HV *stash = gv_stashpv("Event::Stats", 1);
	newCONSTSUB(stash, "MINTIME", newSViv(PE_STAT_SECONDS));
	newCONSTSUB(stash, "MAXTIME",
	      newSViv(PE_STAT_SECONDS * PE_STAT_I1 * PE_STAT_I2));
	I_EVENT_API(HvNAME(stash));
	GEventAPI->install_stats(&Myvtbl);
     }

void
_enforcing_max_callback_time()
     PPCODE:
{
    XPUSHs(boolSV(EnforceMaxCBTime));
}

void
_enforce_max_callback_time(yes)
	bool yes
	PPCODE:
{
    XPUSHs(boolSV(EnforceMaxCBTime));
    if (!EnforceMaxCBTime ^ !yes)
	use_stats(yes? 1:-1);
    EnforceMaxCBTime = yes;
    if (!yes) alarm(0);
}

int
round_seconds(sec)
	int sec;
	CODE:
	if (sec <= 0)
	  RETVAL = PE_STAT_SECONDS;
	else if (sec < PE_STAT_SECONDS * PE_STAT_I1)
	  RETVAL = ((int)(sec + PE_STAT_SECONDS-1)/ PE_STAT_SECONDS) *
			PE_STAT_SECONDS;
	else if (sec < PE_STAT_SECONDS * PE_STAT_I1 * PE_STAT_I2)
	  RETVAL = ((int)(sec + PE_STAT_SECONDS * PE_STAT_I1 - 1) /
			       (PE_STAT_SECONDS * PE_STAT_I1)) *
			PE_STAT_SECONDS * PE_STAT_I1;
	else
	  RETVAL = PE_STAT_SECONDS * PE_STAT_I1 * PE_STAT_I2;
	OUTPUT:
	RETVAL

void
idle_time(sec)
	int sec
	PREINIT:
	int ran, die;
	double elapse;
	PPCODE:
	if (!Stats) croak("Event::Stats are not enabled");
	pe_stat_query(&idleStats, sec, &ran, &die, &elapse);
	XPUSHs(sv_2mortal(newSViv(ran)));
	XPUSHs(sv_2mortal(newSViv(die)));
	XPUSHs(sv_2mortal(newSVnv(elapse)));

void
total_time(sec)
	int sec
	PREINIT:
	int ran,die;
	double elapse;
	PPCODE:
	if (!Stats) croak("Event::Stats are not enabled");
	pe_stat_query(&totalStats, sec, &ran, &die, &elapse);
	XPUSHs(sv_2mortal(newSVnv(elapse)));

int
collect(yes)
	int yes
	CODE:
{
    use_stats(yes);
    RETVAL = Stats;
}
	OUTPUT:
	RETVAL

MODULE = Event::Stats		PACKAGE = Event::Watcher

void
stats(obj, sec)
	SV *obj
	int sec
	PREINIT:
	int ran, die;
	double elapse;
	pe_watcher *THIS;
	PPCODE:
	if (!Stats)
		croak("Event::Stats are not enabled");
	THIS = (pe_watcher*) GEventAPI->sv_2watcher(obj);
	if (THIS->stats)
	  pe_stat_query(THIS->stats, sec, &ran, &die, &elapse);
	else
	  ran = die = elapse = 0;
	XPUSHs(sv_2mortal(newSViv(ran)));
	XPUSHs(sv_2mortal(newSViv(die)));
	XPUSHs(sv_2mortal(newSVnv(elapse)));



( run in 1.638 second using v1.01-cache-2.11-cpan-71847e10f99 )