Skip to content

Commit

Permalink
CPU_watcher: 修改mq_delay 中的输出逻辑 & 增加cpu_watcher测试功能 (#795)
Browse files Browse the repository at this point in the history
* 调整cpu_watcher架构 && 更改Makefile文件

* Update README.md

完善README

* 优化代码

* modify syscall_image

* modify print_mqdelay

* add the test_cpuwatcher.c & mq_test_sender.c & mq_test_receiver.c

---------

Co-authored-by: xhb <[email protected]>
Co-authored-by: 徐晗博 <[email protected]>
  • Loading branch information
3 people authored May 17, 2024
1 parent 4caf289 commit 635deeb
Show file tree
Hide file tree
Showing 5 changed files with 284 additions and 16 deletions.
35 changes: 19 additions & 16 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static const struct argp_option opts[] = {
{"syscall_delay", 'S', 0,0,"print syscall_delay (the data of syscall)"},
{"preempt_time", 'p', 0,0,"print preempt_time (the data of preempt_schedule)"},
{"schedule_delay", 'd', 0,0,"print schedule_delay (the data of cpu)"},
{"mq_delay", 'm', 0,0,"print mq_delay"},
{"mq_delay", 'm', 0,0,"print mq_delay(the data of proc)"},
{ NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" },
{0},
};
Expand Down Expand Up @@ -470,22 +470,24 @@ static int mq_event(void *ctx, void *data,unsigned long data_sz)
{
time_t now = time(NULL);// 获取当前时间
struct tm *localTime = localtime(&now);// 将时间转换为本地时间结构
printf("\n\nTime: %02d:%02d:%02d\n",localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
printf("-----------------------------------------------------------------------------------------------------------------------\n");
const struct mq_events *e = data;

printf("Mqdes: %-8d msg_len: %-8lu msg_prio: %-8u\n",e->mqdes,e->msg_len,e->msg_prio);
printf("SND_PID: %-8d SND_enter_time: %-16llu SND_exit_time: %-16llu\n",
e->send_pid,e->send_enter_time,e->send_exit_time);
printf("RCV_PID: %-8d RCV_enter_time: %-16llu RCV_exit_time: %-16llu\n",
e->rcv_pid,e->rcv_enter_time,e->rcv_exit_time);
printf("-------------------------------------------------------------------------------\n");

printf("SND_Delay/ms: %-8.2f RCV_Delay/ms: %-8.2f Delay/ms: %-8.5f\n",
(e->send_exit_time - e->send_enter_time)/1000000.0,
(e->rcv_exit_time - e->rcv_enter_time)/1000000.0,
(e->rcv_exit_time - e->send_enter_time)/1000000.0);
printf("-----------------------------------------------------------------------------------------------------------------------\n\n");
float send_delay,rcv_delay,delay;
if(!e->send_enter_time || !e->send_exit_time || !e->rcv_enter_time || !e->rcv_exit_time) {
printf("erro!\n");
return 0;
}
send_delay = (e->send_exit_time - e->send_enter_time)/1000000.0;
rcv_delay = (e->rcv_exit_time - e->rcv_enter_time)/1000000.0;
if(e->send_enter_time < e->rcv_enter_time){
delay = (e->rcv_exit_time - e->send_enter_time)/1000000.0;
}else{
delay = (e->rcv_exit_time - e->send_enter_time)/1000000.0 + send_delay + rcv_delay;
}
printf("%02d:%02d:%02d %-8llu %-8lu %-8lu \t%-16ld %-16ld %-16ld %-16ld\t%-15.5f %-15.5f %-15.5f\n",
localTime->tm_hour, localTime->tm_min, localTime->tm_sec,
e->mqdes,e->send_pid,e->rcv_pid,
e->send_enter_time,e->send_exit_time,e->rcv_enter_time,e->rcv_exit_time,
send_delay,rcv_delay,delay);

return 0;
}
Expand Down Expand Up @@ -669,6 +671,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto mq_delay_cleanup;
}
printf("%-8s %-8s %-8s %-8s \t%-16s %-16s %-16s %-16s\t%-15s %-15s %-15s\n","Time","Mqdes","SND_PID","RCV_PID","SND_Enter","SND_EXit","RCV_Enter","RCV_EXit","SND_Delay/ms","RCV_Delay/ms","Delay/ms");
rb = ring_buffer__new(bpf_map__fd(mq_skel->maps.rb), mq_event, NULL, NULL); //ring_buffer__new() API,允许在不使用额外选项数据结构下指定回调
if (!rb) {
err = -1;
Expand Down
18 changes: 18 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CC = gcc
CFLAGS = -Wall -Wextra
LDFLAGS = -lrt

.PHONY: all clean

all: test_cpuwatcher sender receiver

sender: mq_test_sender.c
$(CC) $(CFLAGS) -o sender mq_test_sender.c $(LDFLAGS)

receiver: mq_test_receiver.c
$(CC) $(CFLAGS) -o receiver mq_test_receiver.c $(LDFLAGS)

test_cpuwatcher: test_cpuwatcher.c
$(CC) $(CFLAGS) -o test_cpuwatcher test_cpuwatcher.c
clean:
rm -f test_cpuwatcher sender receiver
37 changes: 37 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_receiver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

#define QUEUE_NAME "/test_queue"
#define MSG_SIZE 50

int main() {
mqd_t mq;
char msg_buffer[MSG_SIZE];
unsigned int priority;

// 打开消息队列
mq = mq_open(QUEUE_NAME, O_RDONLY);
if (mq == (mqd_t)-1) {
perror("mq_open");
exit(1);
}

// 接收消息
while (1) {
if (mq_receive(mq, msg_buffer, MSG_SIZE, &priority) == -1) {
perror("mq_receive");
break;
}
printf("Received: %s\n", msg_buffer);
}

// 关闭消息队列
mq_close(mq);

return 0;
}
49 changes: 49 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_sender.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

#define QUEUE_NAME "/test_queue"
#define MSG_SIZE 50
#define MAX_MSGS 10

int main() {
mqd_t mq;
struct mq_attr attr;
char msg_buffer[MSG_SIZE];
unsigned int priority = 1;
int i;

// 设置消息队列属性
attr.mq_flags = 0;
attr.mq_maxmsg = MAX_MSGS;
attr.mq_msgsize = MSG_SIZE;
attr.mq_curmsgs = 0;

// 创建或打开消息队列
mq = mq_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0644, &attr);
if (mq == (mqd_t)-1) {
perror("mq_open");
exit(1);
}

// 发送消息
for (i = 0;i<60 ; i++) {
sprintf(msg_buffer, "Message %d", i);
if (mq_send(mq, msg_buffer, strlen(msg_buffer) + 1, priority) == -1) {
perror("mq_send");
break;
}
printf("Sent: %s\n", msg_buffer);
sleep(1);
}

// 关闭消息队列
mq_close(mq);
mq_unlink(QUEUE_NAME);

return 0;
}
161 changes: 161 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Copyright 2024 The LMP Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// author: [email protected] [email protected] [email protected]
//
// process image of the user test program

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <argp.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <linux/fcntl.h>
#include <string.h>

#define gettid() syscall(__NR_gettid)

static struct env {
bool sar_test;
bool cs_delay_test;
bool sc_delay_test;
bool mq_delay_test;
bool preempt_test;
bool schedule_test;
} env = {
.sar_test = false,
.cs_delay_test = false,
.sc_delay_test = false,
.mq_delay_test = false,
.preempt_test = false,
.schedule_test = false,
};

const char argp_program_doc[] ="To test cpu_watcher.\n";

static const struct argp_option opts[] = {
{ "sar", 's', NULL, 0, "To test sar" },
{ "cs_delay", 'c', NULL, 0, "To test cs_delay" },
{ "sc_delay", 'S', NULL, 0, "To test sc_delay" },
{ "mq_delay", 'm', NULL, 0, "To test mq_delay" },
{ "preempt_delay", 'p', NULL, 0, "To test preempt_delay" },
{ "schedule_delay", 'd', NULL, 0, "To test schedule_delay"},
{ "all", 'a', NULL, 0, "To test all" },
{ NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" },
{},
};

static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
switch (key) {
case 'a':
env.sar_test = true;
env.cs_delay_test = true;
env.mq_delay_test = true;
env.preempt_test = true;
env.sc_delay_test = true;
env.schedule_test = true;
break;
case 's':
env.sar_test = true;
break;
case 'c':
env.cs_delay_test = true;
break;
case 'S':
env.sc_delay_test = true;
break;
case 'm':
env.mq_delay_test = true;
break;
case 'p':
env.preempt_test = true;
break;
case 'd':
env.schedule_test = true;
break;
case 'h':
argp_state_help(state, stderr, ARGP_HELP_STD_HELP);
break;
default:
return ARGP_ERR_UNKNOWN;
}

return 0;
}

void *func(void *arg)
{
int tpid;

tpid = gettid();
printf("新线程pid:%d,睡眠3s后退出\n",tpid);
sleep(3);
printf("新线程退出\n");
}

int main(int argc, char **argv){
int pid,stop;
int err;
pthread_t tid;
static const struct argp argp = {
.options = opts,
.parser = parse_arg,
.doc = argp_program_doc,
};

err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
if (err)
return err;

pid = getpid();
printf("test_proc进程的PID:【%d】\n", pid);
printf("输入任意数字继续程序的运行:");
scanf("%d",&stop); // 使用时将其取消注释
printf("程序开始执行...\n");
printf("\n");

if(env.sar_test){
/*sar的测试代码*/
}

if(env.cs_delay_test){
/*cs_delay的测试代码*/
}

if(env.sc_delay_test){
/*sc_delay的测试代码*/
}

if(env.mq_delay_test){
/*mq_delay的测试代码*/
system("./sender & ./receiver");
sleep(60);
system("^Z");
}

if(env.preempt_test){
/*preempt_delay的测试代码*/
}

if(env.schedule_test){
/*schedule_delay的测试代码*/
}

return 0;
}

0 comments on commit 635deeb

Please sign in to comment.