hipe_perfctr.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 212 行

C
212
字号
/* $Id$ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "sys.h"#include "error.h"#include "global.h"#include "bif.h"#include "big.h"#include "erl_binary.h"#include "hipe_perfctr.h"#include "libperfctr.h"static struct vperfctr *vperfctr;static unsigned int have_rdtsc;static double tsc_to_ms;static unsigned int tsc_on; /* control calls must set tsc_on if have_rdtsc is true */static unsigned int nractrs;static unsigned int users;#define USER_BIFS	(1<<0)#define USER_HRVTIME	(1<<1)static int hipe_perfctr_open(unsigned int user){    struct perfctr_info info;    if (!vperfctr) {	vperfctr = vperfctr_open();	if (!vperfctr)	    return -1;	if (vperfctr_info(vperfctr, &info) >= 0) {	    tsc_to_ms = (double)(info.tsc_to_cpu_mult ? : 1) / (double)info.cpu_khz;	    have_rdtsc = (info.cpu_features & PERFCTR_FEATURE_RDTSC) ? 1 : 0;	}	tsc_on = 0;	nractrs = 0;    }    users |= user;    return 0;}static void hipe_perfctr_reset(void){    struct vperfctr_control control;    memset(&control, 0, sizeof control);    if (have_rdtsc)	control.cpu_control.tsc_on = 1;    nractrs = 0;    if (vperfctr_control(vperfctr, &control) >= 0)	tsc_on = 1;}static void hipe_perfctr_close(unsigned int user){    if (!vperfctr)	return;    users &= ~user;    switch (users) {      case 0:	vperfctr_unlink(vperfctr);	vperfctr_close(vperfctr);	vperfctr = NULL;	tsc_on = 0;	nractrs = 0;	break;      case USER_HRVTIME:	hipe_perfctr_reset();    }}/* * Interface for HiPE's hrvtime code. */int hipe_perfctr_hrvtime_open(void){    if (hipe_perfctr_open(USER_HRVTIME) < 0)	return -1;    if (have_rdtsc) {	if (!tsc_on)	    hipe_perfctr_reset(); /* note: updates tsc_on */	if (tsc_on)	    return 0;    }    hipe_perfctr_hrvtime_close();    return -1;}void hipe_perfctr_hrvtime_close(void){    hipe_perfctr_close(USER_HRVTIME);}double hipe_perfctr_hrvtime_get(void){    return (double)vperfctr_read_tsc(vperfctr) * tsc_to_ms;}/* * BIF interface for user-programmable performance counters. */BIF_RETTYPE hipe_bifs_vperfctr_open_0(BIF_ALIST_0){    if (hipe_perfctr_open(USER_BIFS) < 0)	BIF_RET(am_false); /* arity 0 BIFs can't fail :-( */    BIF_RET(am_true);}BIF_RETTYPE hipe_bifs_vperfctr_close_0(BIF_ALIST_0){    hipe_perfctr_close(USER_BIFS);    BIF_RET(NIL);}static Eterm ull_to_integer(unsigned long long x, Process *p){    unsigned long long tmpx;    unsigned int ds, i;    size_t sz;    Eterm *hp;    digit_t *xp;    if (x <= (unsigned long long)MAX_SMALL)	return make_small(x);    /* Calculate number of digits. */    ds = 0;    tmpx = x;    do {	++ds;	tmpx >>= D_EXP;    } while (tmpx != 0);    sz = BIG_NEED_SIZE(ds);	/* number of words including arity */    hp = HAlloc(p, sz);    *hp = make_pos_bignum_header(sz-1);    xp = (digit_t*)(hp+1);    i = 0;    do {	xp[i++] = (digit_t)x;	x >>= D_EXP;    } while (i < ds);    while (i & (BIG_DIGITS_PER_WORD-1))	xp[i++] = 0;    return make_big(hp);}BIF_RETTYPE hipe_bifs_vperfctr_info_0(BIF_ALIST_0){    struct perfctr_info info;    if (!vperfctr || vperfctr_info(vperfctr, &info) < 0)	BIF_RET(am_false); /* arity 0 BIFs can't fail :-( */    BIF_RET(new_binary(BIF_P, (void*)&info, sizeof info));}BIF_RETTYPE hipe_bifs_vperfctr_read_tsc_0(BIF_ALIST_0){    unsigned long long val;    if (!vperfctr || !tsc_on)	BIF_RET(am_false); /* arity 0 BIFs can't fail :-( */    val = vperfctr_read_tsc(vperfctr);    BIF_RET(ull_to_integer(val, BIF_P));}BIF_RETTYPE hipe_bifs_vperfctr_read_pmc_1(BIF_ALIST_1){    Uint pmc;    unsigned long long val;    if (!vperfctr ||	is_not_small(BIF_ARG_1) ||	(pmc = unsigned_val(BIF_ARG_1), pmc >= nractrs))	BIF_RET(am_false); /* for consistency with the arity 0 BIFs */    val = vperfctr_read_pmc(vperfctr, pmc);    BIF_RET(ull_to_integer(val, BIF_P));}BIF_RETTYPE hipe_bifs_vperfctr_control_1(BIF_ALIST_1){    void *bytes;    struct vperfctr_control control;    Uint bitoffs;    Uint bitsize;    if (!vperfctr)	BIF_ERROR(BIF_P, BADARG);    if (is_not_binary(BIF_ARG_1))	BIF_ERROR(BIF_P, BADARG);    if (binary_size(BIF_ARG_1) != sizeof control)	BIF_ERROR(BIF_P, BADARG);    ERTS_GET_BINARY_BYTES(BIF_ARG_1, bytes, bitoffs, bitsize);    ASSERT(bitoffs == 0);    ASSERT(bitsize == 0);    memcpy(&control, bytes, sizeof control);    if (have_rdtsc)	control.cpu_control.tsc_on = 1;    if (vperfctr_control(vperfctr, &control) < 0) {	hipe_perfctr_reset();	BIF_ERROR(BIF_P, BADARG);    }    tsc_on = control.cpu_control.tsc_on;    nractrs = control.cpu_control.nractrs;    BIF_RET(NIL);}

⌨️ 快捷键说明

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