perf_event性能事件循环

性能事件管道循环

int evpipe_loop(evpipe_t *evp, int *sig, int strict) {
	int cpu, err, ready;
	//性能事件循环
	for (;!(*sig);) {
		//监测性能事件
		ready = poll(evp->poll, evp->ncpus, -1);
		if (ready <= 0) return ready ? : 0;
        //如果准备好了, 我们直接读取对应的性能事件
		for (cpu = 0; ready && (cpu < evp->ncpus); cpu++) {
			if (!(evp->poll[cpu].revents & POLLIN))
				continue;
             //不断的提取
			err = evqueue_drain(&evp->q[cpu], strict);
			ready--;
		}
	}

	return 0;
}

下面是核心的实现:

int evqueue_drain(struct evqueue *q, int strict) {
	struct lost_event *lost;
	uint64_t size, offs, head, tail;
	uint8_t *base, *this, *next;
	event_t *ev;
	int err = 0;

	size = q->mem->data_size;
	offs = q->mem->data_offset;
	base = (uint8_t *)q->mem + offs;

	for (head = __get_head(q->mem); q->mem->data_tail != head;
	     __set_tail(q->mem, q->mem->data_tail + ev->hdr.size)) {
		tail = q->mem->data_tail;

		this = base + (tail % size);
		ev   = (void *)this;
		next = base + ((tail + ev->hdr.size) % size);

		if (next < this) {
			size_t left = (base + size) - this;

			q->buf = realloc(q->buf, ev->hdr.size);
			memcpy(q->buf, this, left);
			memcpy(q->buf + left, base, ev->hdr.size - left);
			ev = q->buf;
		}

		switch (ev->hdr.type) {
		//如果是普通的事件直接返回
		case PERF_RECORD_SAMPLE:
			err = event_handle(ev, ev->hdr.size);
			break;

		case PERF_RECORD_LOST:
			lost = (void *)ev;

			if (strict) {
				_e("lost %"PRId64" events", lost->lost);
				err = -EOVERFLOW;
			} else {
				_w("lost %"PRId64" events", lost->lost);
			}
			break;

		default:
			_e("unknown perf event %#"PRIx32, ev->hdr.type);
			err = -EINVAL;
			break;
		}

		if (err)
			break;
	}

	return err;
}

在这个流程图中,我使用了Mermaid语法来描述evqueue_drain函数的主要步骤:

  • 开始执行函数。
  • 初始化所有必要的变量。
  • 获取内存中事件队列的头部指针。
  • 进入循环,条件是队列的尾部指针不等于头部指针。
  • 获取内存中事件队列的尾部指针。
  • 计算当前事件的内存地址。
  • 计算下一个事件的内存地址。
  • 检查当前事件是否跨越了环形缓冲区的边界。
  • 如果事件跨越边界,则重新分配缓冲区并复制事件内容。
  • 根据事件类型处理事件:
  • 如果是采样事件(PERF_RECORD_SAMPLE),调用event_handle函数。
  • 如果是丢失事件(PERF_RECORD_LOST),根据strict标志打印错误或警告。
  • 对于未知事件类型,打印错误信息。
  • 检查是否有错误发生。
  • 如果没有错误,继续循环。
  • 如果有错误,结束循环。
  • 结束函数。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值