📄 profil.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * profil.c (proc) * * Profile functions */#include "prcmgr.h"#include <longlong.h>LOCAL void profil_task(VOID);LOCAL void profil_cychandler(VOID);LOCAL WER init_profil(void);/* Profile definition structure*/typedef struct _profil { struct _profil *next; /* Link list */ W pid; /* Process ID */ UH *buf; /* Histogram buffer */ UW bufsiz; /* Buffer size (in UH) */ UW offset; /* PC offset */ UW scale; /* PC scaling */} PROFIL;#define TSD_INP_PRO_M1 (-1)LOCAL PROFIL *proflist = NULL; /* Profile definition list */LOCAL W prof_cyc = TSD_INP_PRO_M1; /* Cyclic handler ID */LOCAL W prof_tid = TSD_INP_PRO_M1; /* Task ID */LOCAL W runtaskid; /* Runtime task ID */#define PROFTSK_PRI 10 /* Priority of profile task */#define PROFTSK_STKSZ 1024 /* Profile task stack */#define PROFTSK_PERIOD 10 /* Profile task cycle */#define TSD_PFT_IX_2 2#define TSD_PFT_IX_0X10000 0x10000U#define TSD_PFT_BUF_0XFFFF (UH)0xFFFF/* Profile processing task*/LOCAL void profil_task(VOID){ W ix, tid; PINFO *pi; PROFIL *p; T_EIT eit; /* Do not terminate a task once it has started. */ for (;;) { /* Wait for wakeup */ tk_slp_tsk(TMO_FEVR); tid = runtaskid; if (tid == 0) { continue; } Lock(&ProcMgrLock); /* Fetch task PINFO: Ignore non-process */ pi = GetPinfo(tid); if (pi == NULL) { goto IGNORE; } /* Ignore a process if it is not intended for profiling. */ for (p = proflist;(( p != NULL )&&(p->pid != pi->procid)); p = p->next){ ; } if (p == NULL) { goto IGNORE; } /* Profile updating */ if (tk_get_reg(tid, NULL, &eit, NULL) < 0) { goto IGNORE; } ix = (W)((UW)eit.PC - p->offset); if (ix >= 0) { ix = (W)lltol(li_div((li_mul(ltoll(ix), (longlong)p->scale)), (longlong)(TSD_PFT_IX_0X10000 * TSD_PFT_IX_2) /* HASHFRACTION */)); if (ix < (W)p->bufsiz) { (void)SetTaskSpace(tid); if (p->buf[ix] != TSD_PFT_BUF_0XFFFF) { p->buf[ix]++; } (void)SetTaskSpace(TSK_SELF); } }IGNORE: Unlock(&ProcMgrLock); }}/* Profile cyclic start handler: Wakes up profile processing task cyclically*/LOCAL void profil_cychandler(VOID){ T_RSYS rsys; tk_ref_sys(&rsys); runtaskid = rsys.runtskid; if (runtaskid != 0) { tk_wup_tsk(prof_tid); }}/* Initialize profile function*/LOCAL WER init_profil(void){ W er; T_CTSK ctsk; T_CCYC ccyc; /* Generate/start profile processing task */ SetOBJNAME(ctsk.exinf, "PROF"); ctsk.itskpri = PROFTSK_PRI; ctsk.stksz = PROFTSK_STKSZ; ctsk.task = profil_task; ctsk.tskatr = TA_HLNG | TA_RNG0; prof_tid = er = tk_cre_tsk(&ctsk); if (er >= E_OK) { er = tk_sta_tsk(prof_tid, 0); } if (er < E_OK) { goto EEXIT; } /* Definitions of cyclic start handler */ SetOBJNAME(ccyc.exinf, "PROF"); ccyc.cycatr = TA_HLNG | TA_PHS; ccyc.cychdr = profil_cychandler; ccyc.cyctim = PROFTSK_PERIOD; ccyc.cycphs = 0; prof_cyc = er = tk_cre_cyc(&ccyc); if (er >= E_OK) { return E_OK; }EEXIT: if (prof_tid >= E_OK) { tk_del_tsk(prof_tid); } prof_tid = prof_cyc = TSD_INP_PRO_M1; return ERtoERR(er);}/* Control profile: system call*/EXPORT WER pi_profil(PINFO *pi, P_PROFILINF *pbuf){ W er; PROFIL *p, *prev; if (pbuf == NULL) { /* Terminate profile */ prev = (PROFIL*)&proflist; for (p = proflist; p != NULL; p = p->next) { if (p->pid != pi->procid) { continue; } prev->next = p->next; Kfree(p); /* Stop cyclic handler */ if ((proflist == NULL )&&( prof_cyc >= 0)) { tk_stp_cyc(prof_cyc); } return E_OK; } return E_PAR; } /* Initialize profile functions */ if (prof_cyc < 0) { er = init_profil(); if (er < E_OK) { return er; } } /* Start profile */ if (((er = CheckSpaceR(pbuf, sizeof(P_PROFILINF))) < E_OK )|| ((er = CheckSpaceRW(pbuf->buf, (W)pbuf->bufsiz)) < E_OK)) { return er; } /* Register PROFIL */ p = Kmalloc(sizeof(PROFIL)); p->pid = pi->procid; p->buf = pbuf->buf; p->bufsiz = pbuf->bufsiz / sizeof(UH); p->offset = pbuf->offset; p->scale = pbuf->scale; p->next = proflist; proflist = p; /* Start cyclic handler */ tk_sta_cyc(prof_cyc); return E_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -