Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPU_watcher: 修改mq_delay 中的输出逻辑 & 增加cpu_watcher测试功能 #795

Merged
merged 10 commits into from
May 17, 2024
35 changes: 19 additions & 16 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{"mq_delay", 'm', 0,0,"print mq_delay"},
这种帮助说明要解释清楚,看着解释了又好像没解释。
另外你采集的这个时间要有对应的测试程序,测试截图,去验证你的算法是否符合实际。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已经增加测试程序及测试截图, 更改解释

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
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;
}
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;
}
Loading