diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c index fa735c39e..adb062e2c 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c @@ -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}, }; @@ -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; } @@ -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; diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/Makefile b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/Makefile new file mode 100644 index 000000000..f8b5bb833 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/Makefile @@ -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 diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_receiver.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_receiver.c new file mode 100644 index 000000000..240202514 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_receiver.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_sender.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_sender.c new file mode 100644 index 000000000..43c66e55b --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_sender.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c new file mode 100644 index 000000000..87fcf2431 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c @@ -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: albert_xuu@163.com zhangxy1016304@163.com zhangziheng0525@163.com +// +// process image of the user test program + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +}