⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dprof.xs

📁 Altera recommends the following system configuration: * Pentium II 400 with 512-MB system memory (fa
💻 XS
📖 第 1 页 / 共 2 页
字号:
#define PERL_NO_GET_CONTEXT#include "EXTERN.h"#include "perl.h"#include "XSUB.h"/*#define DBG_SUB 1      *//*#define DBG_TIMER 1    */#ifdef DBG_SUB#  define DBG_SUB_NOTIFY(A,B) warn(A, B)#else#  define DBG_SUB_NOTIFY(A,B)  /* nothing */#endif#ifdef DBG_TIMER#  define DBG_TIMER_NOTIFY(A) warn(A)#else#  define DBG_TIMER_NOTIFY(A)  /* nothing */#endif/* HZ == clock ticks per second */#ifdef VMS#  define HZ ((I32)CLK_TCK)#  define DPROF_HZ HZ#  include <starlet.h>  /* prototype for sys$gettim() */#  include <lib$routines.h>#  define Times(ptr) (dprof_times(aTHX_ ptr))#else#  ifndef HZ#    ifdef CLK_TCK#      define HZ ((I32)CLK_TCK)#    else#      define HZ 60#    endif#  endif#  ifdef OS2				/* times() has significant overhead */#    define Times(ptr) (dprof_times(aTHX_ ptr))#    define INCL_DOSPROFILE#    define INCL_DOSERRORS#    include <os2.h>#    define toLongLong(arg) (*(long long*)&(arg))#    define DPROF_HZ g_dprof_ticks#  else#    define Times(ptr) (times(ptr))#    define DPROF_HZ HZ#  endif #endifXS(XS_Devel__DProf_END);        /* used by prof_mark() *//* Everything is built on times(2).  See its manpage for a description * of the timings. */union prof_any {        clock_t tms_utime;  /* cpu time spent in user space */        clock_t tms_stime;  /* cpu time spent in system */        clock_t realtime;   /* elapsed real time, in ticks */        char *name;        U32 id;        opcode ptype;};typedef union prof_any PROFANY;typedef struct {    U32		dprof_ticks;    char*	out_file_name;	/* output file (defaults to tmon.out) */    PerlIO*	fp;		/* pointer to tmon.out file */    long	TIMES_LOCATION;	/* Where in the file to store the time totals */    int		SAVE_STACK;	/* How much data to buffer until end of run */    int		prof_pid;	/* pid of profiled process */    struct tms	prof_start;    struct tms	prof_end;    clock_t	rprof_start;	/* elapsed real time ticks */    clock_t	rprof_end;    clock_t	wprof_u;    clock_t	wprof_s;    clock_t	wprof_r;    clock_t	otms_utime;    clock_t	otms_stime;    clock_t	orealtime;    PROFANY*	profstack;    int		profstack_max;    int		profstack_ix;    HV*		cv_hash;    U32		total;    U32		lastid;    U32		default_perldb;    U32		depth;#ifdef OS2    ULONG	frequ;    long long	start_cnt;#endif#ifdef PERL_IMPLICIT_CONTEXT#  define register    pTHX;#  undef register#endif} prof_state_t;prof_state_t g_prof_state;#define g_dprof_ticks		g_prof_state.dprof_ticks#define g_out_file_name		g_prof_state.out_file_name#define g_fp			g_prof_state.fp#define g_TIMES_LOCATION	g_prof_state.TIMES_LOCATION#define g_SAVE_STACK		g_prof_state.SAVE_STACK#define g_prof_pid		g_prof_state.prof_pid#define g_prof_start		g_prof_state.prof_start#define g_prof_end		g_prof_state.prof_end#define g_rprof_start		g_prof_state.rprof_start#define g_rprof_end		g_prof_state.rprof_end#define g_wprof_u		g_prof_state.wprof_u#define g_wprof_s		g_prof_state.wprof_s#define g_wprof_r		g_prof_state.wprof_r#define g_otms_utime		g_prof_state.otms_utime#define g_otms_stime		g_prof_state.otms_stime#define g_orealtime		g_prof_state.orealtime#define g_profstack		g_prof_state.profstack#define g_profstack_max		g_prof_state.profstack_max#define g_profstack_ix		g_prof_state.profstack_ix#define g_cv_hash		g_prof_state.cv_hash#define g_total			g_prof_state.total#define g_lastid		g_prof_state.lastid#define g_default_perldb	g_prof_state.default_perldb#define g_depth			g_prof_state.depth#ifdef PERL_IMPLICIT_CONTEXT#  define g_THX			g_prof_state.aTHX#endif#ifdef OS2#  define g_frequ		g_prof_state.frequ#  define g_start_cnt		g_prof_state.start_cnt#endifclock_tdprof_times(pTHX_ struct tms *t){#ifdef OS2    ULONG rc;    QWORD cnt;    STRLEN n_a;        if (!g_frequ) {	if (CheckOSError(DosTmrQueryFreq(&g_frequ)))	    croak("DosTmrQueryFreq: %s", SvPV(perl_get_sv("!",TRUE),n_a));	else	    g_frequ = g_frequ/DPROF_HZ;	/* count per tick */	if (CheckOSError(DosTmrQueryTime(&cnt)))	    croak("DosTmrQueryTime: %s",		  SvPV(perl_get_sv("!",TRUE), n_a));	g_start_cnt = toLongLong(cnt);    }    if (CheckOSError(DosTmrQueryTime(&cnt)))	    croak("DosTmrQueryTime: %s", SvPV(perl_get_sv("!",TRUE), n_a));    t->tms_stime = 0;    return (t->tms_utime = (toLongLong(cnt) - g_start_cnt)/g_frequ);#else		/* !OS2 */#  ifdef VMS    clock_t retval;    /* Get wall time and convert to 10 ms intervals to     * produce the return value dprof expects */#    if defined(__DECC) && defined (__ALPHA)#      include <ints.h>    uint64 vmstime;    _ckvmssts(sys$gettim(&vmstime));    vmstime /= 100000;    retval = vmstime & 0x7fffffff;#    else    /* (Older hw or ccs don't have an atomic 64-bit type, so we     * juggle 32-bit ints (and a float) to produce a time_t result     * with minimal loss of information.) */    long int vmstime[2],remainder,divisor = 100000;    _ckvmssts(sys$gettim((unsigned long int *)vmstime));    vmstime[1] &= 0x7fff;  /* prevent overflow in EDIV */    _ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder));#    endif    /* Fill in the struct tms using the CRTL routine . . .*/    times((tbuffer_t *)t);    return (clock_t) retval;#  else		/* !VMS && !OS2 */    return times(t);#  endif#endif}static voidprof_dumpa(pTHX_ opcode ptype, U32 id){    if (ptype == OP_LEAVESUB) {	PerlIO_printf(g_fp,"- %"UVxf"\n", (UV)id);    }    else if(ptype == OP_ENTERSUB) {	PerlIO_printf(g_fp,"+ %"UVxf"\n", (UV)id);    }    else if(ptype == OP_GOTO) {	PerlIO_printf(g_fp,"* %"UVxf"\n", (UV)id);    }    else if(ptype == OP_DIE) {	PerlIO_printf(g_fp,"/ %"UVxf"\n", (UV)id);    }    else {	PerlIO_printf(g_fp,"Profiler unknown prof code %d\n", ptype);    }}   static voidprof_dumps(pTHX_ U32 id, char *pname, char *gname){    PerlIO_printf(g_fp,"& %"UVxf" %s %s\n", (UV)id, pname, gname);}   static voidprof_dumpt(pTHX_ long tms_utime, long tms_stime, long realtime){    PerlIO_printf(g_fp,"@ %ld %ld %ld\n", tms_utime, tms_stime, realtime);}   static voidprof_dump_until(pTHX_ long ix){    long base = 0;    struct tms t1, t2;    clock_t realtime1, realtime2;    realtime1 = Times(&t1);    while (base < ix) {	opcode ptype = g_profstack[base++].ptype;	if (ptype == OP_TIME) {	    long tms_utime = g_profstack[base++].tms_utime;	    long tms_stime = g_profstack[base++].tms_stime;	    long realtime = g_profstack[base++].realtime;	    prof_dumpt(aTHX_ tms_utime, tms_stime, realtime);	}	else if (ptype == OP_GV) {	    U32 id = g_profstack[base++].id;	    char *pname = g_profstack[base++].name;	    char *gname = g_profstack[base++].name;	    prof_dumps(aTHX_ id, pname, gname);	}	else {	    U32 id = g_profstack[base++].id;	    prof_dumpa(aTHX_ ptype, id);	}    }    PerlIO_flush(g_fp);    realtime2 = Times(&t2);    if (realtime2 != realtime1 || t1.tms_utime != t2.tms_utime	|| t1.tms_stime != t2.tms_stime) {	g_wprof_r += realtime2 - realtime1;	g_wprof_u += t2.tms_utime - t1.tms_utime;	g_wprof_s += t2.tms_stime - t1.tms_stime;	PerlIO_printf(g_fp,"+ & Devel::DProf::write\n");	PerlIO_printf(g_fp,"@ %"IVdf" %"IVdf" %"IVdf"\n", 		      /* The (IV) casts are one possibility:		       * the Painfully Correct Way would be to		       * have Clock_t_f. */		      (IV)(t2.tms_utime - t1.tms_utime),		      (IV)(t2.tms_stime - t1.tms_stime), 		      (IV)(realtime2 - realtime1));	PerlIO_printf(g_fp,"- & Devel::DProf::write\n");	g_otms_utime = t2.tms_utime;	g_otms_stime = t2.tms_stime;	g_orealtime = realtime2;	PerlIO_flush(g_fp);    }}static voidprof_mark(pTHX_ opcode ptype){    struct tms t;    clock_t realtime, rdelta, udelta, sdelta;    U32 id;    SV *Sub = GvSV(PL_DBsub);	/* name of current sub */    if (g_SAVE_STACK) {	if (g_profstack_ix + 5 > g_profstack_max) {		g_profstack_max = g_profstack_max * 3 / 2;		Renew(g_profstack, g_profstack_max, PROFANY);	}    }    realtime = Times(&t);    rdelta = realtime - g_orealtime;    udelta = t.tms_utime - g_otms_utime;    sdelta = t.tms_stime - g_otms_stime;    if (rdelta || udelta || sdelta) {	if (g_SAVE_STACK) {	    g_profstack[g_profstack_ix++].ptype = OP_TIME;	    g_profstack[g_profstack_ix++].tms_utime = udelta;	    g_profstack[g_profstack_ix++].tms_stime = sdelta;	    g_profstack[g_profstack_ix++].realtime = rdelta;	}	else { /* Write it to disk now so's not to eat up core */	    if (g_prof_pid == (int)getpid()) {		prof_dumpt(aTHX_ udelta, sdelta, rdelta);		PerlIO_flush(g_fp);	    }	}	g_orealtime = realtime;	g_otms_stime = t.tms_stime;	g_otms_utime = t.tms_utime;    }    {	SV **svp;	char *gname, *pname;	CV *cv;	cv = INT2PTR(CV*,SvIVX(Sub));	svp = hv_fetch(g_cv_hash, (char*)&cv, sizeof(CV*), TRUE);	if (!SvOK(*svp)) {	    GV *gv = CvGV(cv);			    sv_setiv(*svp, id = ++g_lastid);	    pname = ((GvSTASH(gv) && HvNAME(GvSTASH(gv))) 		     ? HvNAME(GvSTASH(gv)) 		     : "(null)");	    gname = GvNAME(gv);	    if (CvXSUB(cv) == XS_Devel__DProf_END)		return;	    if (g_SAVE_STACK) { /* Store it for later recording  -JH */		g_profstack[g_profstack_ix++].ptype = OP_GV;		g_profstack[g_profstack_ix++].id = id;		g_profstack[g_profstack_ix++].name = pname;		g_profstack[g_profstack_ix++].name = gname;	    }	    else { /* Write it to disk now so's not to eat up core */		/* Only record the parent's info */		if (g_prof_pid == (int)getpid()) {		    prof_dumps(aTHX_ id, pname, gname);		    PerlIO_flush(g_fp);		}		else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -