├── README.md ├── doc ├── Unixbench.md ├── basic │ ├── basic.md │ └── oscomp_syscalls.md ├── busybox │ ├── busybox.md │ ├── busybox_cmd.txt │ └── busybox_testcode.sh ├── cyclictest │ └── cyclictest.md ├── iperf │ └── iperf.md ├── libcbench │ ├── libcbench.md │ └── libcbench_testcode.sh ├── libctest.md ├── lmbench.md ├── ltp │ └── ltp.md └── lua │ ├── lua.md │ ├── lua_testcode.sh │ └── test.sh ├── judge ├── README.md ├── judge_basic.py ├── judge_busybox.py ├── judge_iozone.py ├── judge_libctest.py ├── judge_lua.py └── lmbench.sh └── lmbench └── lmbench.md /README.md: -------------------------------------------------------------------------------- 1 | # OS大赛赛题协作文档 2 | 3 | ## 进度 4 | 5 | | 题目 | 题目描述 | 编译方法 | 样例输出 | 评分依据 | 6 | | ---------- | -------- | -------- | -------- | -------- | 7 | | basic | ✅ | ✅ | ✅ | ✅ | 8 | | busybox | ✅ | ✅ | ✅ | ✅ | 9 | | lua | ✅ | ✅ | ✅ | ✅ | 10 | | libctest | ✅ | ✅ | ✅ | ✅ | 11 | | iozone | ❌ | ✅ | ❌ | ✅ | 12 | | unixbench | ✅ | ✅ | ✅ | ✅ | 13 | | iperf | ✅ | ✅ | ✅ | ✅ | 14 | | libcbench | ✅ | ✅ | ✅ | ✅ | 15 | | lmbench | ✅ | ✅ | ✅ | ✅ | 16 | | netperf | ❌ | ✅ | ❌ | ✅ | 17 | | cyclictest | ✅ | ✅ | ✅ | ✅ | 18 | | ltp | ✅ | ✅ | ✅ | ✅ | 19 | 20 | ## 说明 21 | 22 | 本届操作系统大赛提供了basic、busybox、lua、libctest、iozone、unixbench、iperf、libcbench、lmbench、netperf、cyclictest和LTP共12组测试题目,[赛题仓库](https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025)有测例源代码等各种信息。 23 | 24 | **注:对上述每个测试题目,需给出题目描述、编译方法、样例输出、评分依据四个部分的测例题目说明信息。我们希望能够有志愿者同学帮助我们进一步完成剩余的测例题目说明信息** 25 | 26 | **请愿意做志愿者的同学参考已经给出 `basic`、`busybox`、`lua`等已完成的测例题目说明信息,提交或改进测例题目说明信息,以Pull request的形式在[本仓库Pull requests](https://github.com/oscomp/oskernel-testsuits-cooperation/pulls)中呈现。需要了解的具体操作如下面的内容所示。** 27 | 28 | **如果在进行分析和具体操作过程中,发现问题,请在[本仓库issues](https://github.com/oscomp/oskernel-testsuits-cooperation/issues)中提出。** 29 | 30 | **志愿者工作是本次比赛评选优秀组织奖和技术贡献奖的重要参考依据。** 31 | 32 | ### 题目描述 33 | 34 | 描述此题目的基本内容和考察目标等信息。 35 | 36 | ### 编译方法 37 | 38 | 即如何通过源代码构建出符合大赛要求的二进制文件。本届大赛要求对每个题目编译出riscv-glibc、riscv-musl、loongarch-glibc、loongarch-musl 4组可执行文件,并将其放在比赛提供的磁盘镜像中供参赛学生使用。 39 | 40 | 使用不同体系结构平台和不同C运行时库进行编译时参数应尽可能相同,减少同一个题目在不同环境中的差异。 41 | 42 | 如果题目ELF文件运行时需要依赖动态链接库或其他磁盘文件(如libctest),请在构建脚本中将所需的文件一并复制到磁盘镜像中。 43 | 44 | 如果题目并非直接以二进制或Shell脚本启动(如LTP使用了基于Python的kirk),考虑到参赛队伍提交的OS不一定能支持完整的Python,因此需要对题目代码进行修改,使其能够以纯Shell脚本或二进制文件直接启动。 45 | 46 | 题目编译构建时应使用[赛题仓库](https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025)中提供的Docker镜像环境,并将此部分内容合并回仓库中。合并的内容包括:源代码、构建脚本(Makefile)、启动脚本(judge/xxxxx_testcode.sh)。 47 | 48 | ### 样例输出 49 | 50 | 大赛评分原理为:系统会捕获每一个测试题目的stdout,并根据此输出内容进行评分,因此需在文档中给出若干个有代表性的样例输出,并对其各部分含义做出解释,以便参赛队伍理解题目内容和目标。 51 | 52 | ### 评分依据 53 | 54 | 如何通过上述输出信息给出得分。例如在输出中匹配到什么信息即认为得分有效,应得多少分,对于性能测试样例给出的带宽、耗时等信息通过什么样的公式转换成最终得分。 55 | 56 | 评分脚本可参考本仓库judge目录下的文件,命名统一为judge_xxxxx.py。xxxxx为此测试题目的名称,只能为字母和数字,不能有连字符等其他符号。 57 | 58 | ### 其他 59 | 60 | 如有其他注意事项,请在文档中说明。如果现有条件不能满足题目运行,例如题目仓库中的公共环境(libc.so、链接器、文件系统结构等)不符合题目运行要求,Docker镜像中现有的工具不能编译出题目执行文件,网络相关的题目需要预先准备公共server等,请与我联系更新。 61 | 62 | ## 协作方式 63 | 64 | 首先fork本仓库。 65 | 66 | 随后可在您fork出的仓库中完成上述工作。 67 | 各题目的文档均应放置在doc目录中与题目同名的子目录中,并有一个与题目同名的md文件作为题目文档入口,例如 `doc/basic/basic.md`。文档中应包含上述“题目描述”、“编译方法”、“样例输出”、“评分依据”四个部分。如果描述此题目的信息需要创建多个文档文件或引用图片等,也一并放在子目录中。 68 | 69 | 其中“编译方法项”除在文档中简要描述外,还应将赛题代码、编译脚本和命令合并至[赛题仓库](https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025)。赛题仓库的规则请参考[编译方法](#编译方法)。 70 | 71 | 其中“评测依据”除在文档中描述外,还应提供测试脚本文件。测试脚本应放在本仓库的 `judge`目录下脚本编写规则请参考[测试脚本](judge/README.md)。 72 | 73 | 完成后可在本仓库中发起pull request,从而将您的工作成果合并到本仓库中。 74 | 75 | 关于fork-pr的流程可参考[Github参加开源项目提交PR教程](https://zhuanlan.zhihu.com/p/476477541)。 76 | -------------------------------------------------------------------------------- /doc/Unixbench.md: -------------------------------------------------------------------------------- 1 | ### UnixBench 测试样例说明 2 | 3 | --- 4 | 5 | #### **题目描述** 6 | 7 | UnixBench 测试集用于评估操作系统的综合性能,涵盖 CPU 运算、内存管理、进程调度、文件系统等核心功能。测试程序通过系统调用与内核交互,验证 OS 的正确性和效率。每个测试点对应不同场景,需确保系统调用实现完整且性能达标。 8 | 9 | --- 10 | 11 | #### **测试用例代码** 12 | 13 | 以下是文档中出现的所有测试用例代码文件及其核心功能描述: 14 | 15 | | 文件名 | 测试目标 | 关键指标 | 关键系统调用 | 16 | | ------------------ | -------------------- | ----------------------- | ---------------------------------------------------------- | 17 | | `arith.c` | 算术运算速度 | 运算次数/秒 (lps) | 无(纯CPU计算) | 18 | | `dhry_1/2.c` | 整数运算性能 | Dhrystone MIPS | `malloc`, `execv` | 19 | | `pipe.c` | 进程间通信吞吐量 | 管道操作次数/秒 (lps) | `pipe`, `read`, `write` | 20 | | `syscall.c` | 系统调用延迟 | 系统调用次数/秒 (lps) | `getpid`, `exec`, `close`, `dup`等多种基础系统调用 | 21 | | `fstime.c` | 文件系统I/O速度 | 读写吞吐量 (KBps) | `creat`, `open`, `read`, `write`, `lseek` | 22 | | `hanoi.c` | 递归性能 | 汉诺塔操作次数/秒 (lps) | 无(纯算法计算) | 23 | | `context1.c` | 上下文切换开销 | 切换次数/秒 (lps) | `fork`, `pipe`(通过读写同步切换) | 24 | | `spawn.c` | 进程创建效率 | 进程数/秒 (lps) | `fork`, `wait` | 25 | | `whets.c` | 浮点运算性能 | MFLOPS | 无(依赖数学库函数) | 26 | | `execl.c` | 程序加载效率 | 加载次数/秒 (lps) | `execl`, `fork` | 27 | | `time-polling.c` | 多路I/O复用效率 | 事件处理数/秒 (ops) | `select`, `poll` | 28 | | `looper.c` | 用户态任务调度公平性 | 循环完成次数/秒 (lps) | 无(依赖用户态逻辑) | 29 | 30 | --- 31 | 32 | #### **编译方法** 33 | 34 | 参考 `Makefile` 配置,使用静态链接和优化选项编译: 35 | 36 | ``` 37 | # 编译器配置 38 | CC = riscv64-linux-gcc -static 39 | OPTON = -O3 -ffast-math 40 | CFLAGS = -Wall -pedantic (OPTON) -I (OPTON)−I(SRCDIR) -DTIME 41 | # 编译目标程序(示例:arithoh)(PROGDIR)/arithoh: (PROGDIR)/arithoh:(SRCDIR)/arith.c $(SRCDIR)/timeit.c 42 | (CC) -o (CC)−o@ (CFLAGS) (CFLAGS)<< $(LDFLAGS) 43 | ``` 44 | 45 | 执行编译: 46 | 47 | ``` 48 | make -f Makefile.sub all 49 | ``` 50 | 51 | --- 52 | 53 | #### **样例输出** 54 | 55 | 一个可能的运行输出示例: 56 | 57 | ``` 58 | #### OS COMP TEST GROUP START unixbench #### 59 | ========== START test_arith ========== 60 | COUNT|987654|1|lps 61 | ========== END test_arith ========== 62 | ========== START test_dhrystone ========== 63 | Dhrystone Test: 10.0 MIPS 64 | ========== END test_dhrystone ========== 65 | ========== START test_pipe ========== 66 | Pipe Throughput: 5000 ops/sec 67 | ========== END test_pipe ========== 68 | ========== START test_fstime ========== 69 | File Read: 200 MB/s, Write: 150 MB/s 70 | ========== END test_fstime ========== 71 | #### OS COMP TEST GROUP END unixbench #### 72 | ``` 73 | 74 | **解释** : 75 | 76 | * **`test_dhrystone`** 显示每秒 1000 万次 Dhrystone 操作(MIPS)。 77 | * **`COUNT|987654|1|lps`**:表示在测试持续时间内完成了 987,654 次循环迭代(每秒循环数)。 78 | * **`test_pipe`** 显示每秒处理 5000 次管道操作。 79 | * **`test_fstime`** 显示文件读写速度。 80 | 81 | --- 82 | 83 | #### **评分依据** 84 | 85 | 脚本中无评分依据,实现正确的情况下性能越高越好。 86 | -------------------------------------------------------------------------------- /doc/basic/basic.md: -------------------------------------------------------------------------------- 1 | # Basic基本测试样例 2 | 3 | ## 题目描述 4 | 5 | 这里给出的测试题目会通过系统调用访问内核实现组开发的OS,得到正确可靠的服务。系统调用基于部分比较基础的Linux syscalls。 6 | 7 | 测试用例代码可见[syscalls测试用例](https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025/basic)。从测试用例可以看出,自己开发的OS只需实现Linux syscalls的功能子集即可。 8 | 9 | 具体的Syscall说明可见[syscalls说明](oscomp_syscalls.md)。 10 | 11 | ## 编译方法 12 | 13 | 请参考[赛题仓库](https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025)中的basic目录和Makefile.sub中的basic目标。 14 | 15 | ## 样例输出 16 | 17 | 一次运行正确的输出可能如下所示: 18 | ``` 19 | #### OS COMP TEST GROUP START basic-musl #### 20 | ========== START test_brk ========== 21 | Before alloc,heap pos: 0 22 | After alloc,heap pos: 64 23 | Alloc again,heap pos: 128 24 | ========== END test_brk ========== 25 | ========== START test_chdir ========== 26 | chdir ret: 0 27 | current working dir : /test_chdir/ 28 | ========== END test_chdir ========== 29 | #### OS COMP TEST GROUP END basic-musl #### 30 | ``` 31 | 32 | 首先由basic_testcode.sh输出`#### OS COMP TEST GROUP START basic-musl ####`,随后运行了brk和chdir两个测试程序,最后再由basic_testcode.sh输出对应的`#### OS COMP TEST GROUP END basic-musl ####`。 33 | 34 | 在brk测试点中,进行了两次分配内存操作,每次分配64字节,分别打印出了分配前和两次分配后的堆指针位置。在chdir测试点中,首先调用mkdir创建了/test_chdir目录,并使用chdir进入,检查了chdir调用的返回值为0,最后使用getpwd调用验证当前位置是否在/test_chidr中。 35 | 36 | ## 评分依据 37 | 38 | brk样例成功运行得1分,第一次brk分配结束堆指针在正确位置得1分,第二次分配结束堆指针在正确位置得1分,因此上述输出共得3分。 39 | chdir样例成功运行得1分,chdir调用返回值为0得1分,使用getpwd验证当前目录在/test_chdir中得1分,因此上述输出共得3分。 40 | 41 | 其余所有测试点的详细评分依据可参考[评分脚本](../../judge/judge_basic.py) -------------------------------------------------------------------------------- /doc/basic/oscomp_syscalls.md: -------------------------------------------------------------------------------- 1 | # 系统调用的说明以及调用方式 2 | 系统调用方式遵循RISC-V ABI,即调用号存放在a7寄存器中,6个参数分别储存在a0-a5寄存器 3 | 中,返回值保存在a0中。 4 | 5 | 主要参考了Linux 5.10 syscalls,详细请参见:https://man7.org/linux/man-pages/man2/syscalls.2.html 6 | ## 文件系统相关 7 | ### #define SYS_getcwd 17 8 | 功能:获取当前工作目录; 9 | 10 | 输入: 11 | 12 | - char *buf:一块缓存区,用于保存当前工作目录的字符串。当buf设为NULL,由系统来分配缓存区。 13 | 14 | - size:buf缓存区的大小。 15 | 16 | 返回值:成功执行,则返回当前工作目录的字符串的指针。失败,则返回NULL。 17 | 18 | ```c 19 | char *buf, size_t size; 20 | long ret = syscall(SYS_getcwd, buf, size); 21 | ``` 22 | 23 | ### #define SYS_pipe2 59 24 | 功能:创建管道; 25 | 26 | 输入: 27 | 28 | - fd[2]:用于保存2个文件描述符。其中,fd[0]为管道的读出端,fd[1]为管道的写入端。 29 | 30 | 返回值:成功执行,返回0。失败,返回-1。 31 | 32 | ``` 33 | int fd[2]; 34 | int ret = syscall(SYS_pipe2, fd, 0); 35 | ``` 36 | 37 | ### #define SYS_dup 23 38 | 功能:复制文件描述符; 39 | 40 | 输入: 41 | 42 | - fd:被复制的文件描述符。 43 | 44 | 返回值:成功执行,返回新的文件描述符。失败,返回-1。 45 | 46 | ``` 47 | int fd; 48 | int ret = syscall(SYS_dup, fd); 49 | ``` 50 | 51 | ### #define SYS_dup3 24 52 | 功能:复制文件描述符,并指定了新的文件描述符; 53 | 54 | 输入: 55 | 56 | - old:被复制的文件描述符。 57 | - new:新的文件描述符。 58 | 59 | 返回值:成功执行,返回新的文件描述符。失败,返回-1。 60 | 61 | ``` 62 | int old, int new; 63 | int ret = syscall(SYS_dup3, old, new, 0); 64 | ``` 65 | 66 | ### #define SYS_chdir 49 67 | 功能:切换工作目录; 68 | 69 | 输入: 70 | 71 | - path:需要切换到的目录。 72 | 73 | 返回值:成功执行,返回0。失败,返回-1。 74 | 75 | ``` 76 | const char *path; 77 | int ret = syscall(SYS_chdir, path); 78 | ``` 79 | 80 | ### #define SYS_openat 56 81 | 功能:打开或创建一个文件; 82 | 83 | 输入: 84 | 85 | - fd:文件所在目录的文件描述符。 86 | 87 | - filename:要打开或创建的文件名。如为绝对路径,则忽略fd。如为相对路径,且fd是AT_FDCWD,则filename是相对于当前工作目录来说的。如为相对路径,且fd是一个文件描述符,则filename是相对于fd所指向的目录来说的。 88 | - flags:必须包含如下访问模式的其中一种:O_RDONLY,O_WRONLY,O_RDWR。还可以包含文件创建标志和文件状态标志。 89 | - mode:文件的所有权描述。详见`man 7 inode `。 90 | 91 | 返回值:成功执行,返回新的文件描述符。失败,返回-1。 92 | 93 | ``` 94 | int fd, const char *filename, int flags, mode_t mode; 95 | int ret = syscall(SYS_openat, fd, filename, flags, mode); 96 | ``` 97 | 98 | ### #define SYS_close 57 99 | 功能:关闭一个文件描述符; 100 | 101 | 输入: 102 | 103 | - fd:要关闭的文件描述符。 104 | 105 | 返回值:成功执行,返回0。失败,返回-1。 106 | 107 | ``` 108 | int fd; 109 | int ret = syscall(SYS_close, fd); 110 | ``` 111 | 112 | ### #define SYS_getdents64 61 113 | 功能:获取目录的条目; 114 | 115 | 输入: 116 | 117 | - fd:所要读取目录的文件描述符。 118 | 119 | - buf:一个缓存区,用于保存所读取目录的信息。缓存区的结构如下: 120 | 121 | ```c 122 | struct dirent { 123 | uint64 d_ino; // 索引结点号 124 | int64 d_off; // 到下一个dirent的偏移 125 | unsigned short d_reclen; // 当前dirent的长度 126 | unsigned char d_type; // 文件类型 127 | char d_name[]; //文件名 128 | }; 129 | ``` 130 | 131 | - len:buf的大小。 132 | 133 | 返回值:成功执行,返回读取的字节数。当到目录结尾,则返回0。失败,则返回-1。 134 | 135 | ``` 136 | int fd, struct dirent *buf, size_t len 137 | int ret = syscall(SYS_getdents64, fd, buf, len); 138 | ``` 139 | 140 | ### #define SYS_read 63 141 | 功能:从一个文件描述符中读取; 142 | 143 | 输入: 144 | 145 | - fd:要读取文件的文件描述符。 146 | - buf:一个缓存区,用于存放读取的内容。 147 | - count:要读取的字节数。 148 | 149 | 返回值:成功执行,返回读取的字节数。如为0,表示文件结束。错误,则返回-1。 150 | 151 | ``` 152 | int fd, void *buf, size_t count; 153 | ssize_t ret = syscall(SYS_read, fd, buf, count); 154 | ``` 155 | 156 | ### #define SYS_write 64 157 | 功能:从一个文件描述符中写入; 158 | 159 | 输入: 160 | 161 | - fd:要写入文件的文件描述符。 162 | - buf:一个缓存区,用于存放要写入的内容。 163 | - count:要写入的字节数。 164 | 165 | 返回值:成功执行,返回写入的字节数。错误,则返回-1。 166 | 167 | ``` 168 | int fd, const void *buf, size_t count; 169 | ssize_t ret = syscall(SYS_write, fd, buf, count); 170 | ``` 171 | 172 | ### #define SYS_linkat 37 173 | 功能:创建文件的链接; 174 | 175 | 输入: 176 | 177 | - olddirfd:原来的文件所在目录的文件描述符。 178 | - oldpath:文件原来的名字。如果oldpath是相对路径,则它是相对于olddirfd目录而言的。如果oldpath是相对路径,且olddirfd的值为AT_FDCWD,则它是相对于当前路径而言的。如果oldpath是绝对路径,则olddirfd被忽略。 179 | - newdirfd:新文件名所在的目录。 180 | - newpath:文件的新名字。newpath的使用规则同oldpath。 181 | - flags:在2.6.18内核之前,应置为0。其它的值详见`man 2 linkat`。 182 | 183 | 返回值:成功执行,返回0。失败,返回-1。 184 | 185 | ``` 186 | int olddirfd, char *oldpath, int newdirfd, char *newpath, unsigned int flags 187 | int ret = syscall(SYS_linkat, olddirfd, oldpath, newdirfd, newpath, flags); 188 | ``` 189 | 190 | ### #define SYS_unlinkat 35 191 | 功能:移除指定文件的链接(可用于删除文件); 192 | 193 | 输入: 194 | 195 | - dirfd:要删除的链接所在的目录。 196 | - path:要删除的链接的名字。如果path是相对路径,则它是相对于dirfd目录而言的。如果path是相对路径,且dirfd的值为AT_FDCWD,则它是相对于当前路径而言的。如果path是绝对路径,则dirfd被忽略。 197 | - flags:可设置为0或AT_REMOVEDIR。 198 | 199 | 返回值:成功执行,返回0。失败,返回-1。 200 | 201 | ``` 202 | int dirfd, char *path, unsigned int flags; 203 | syscall(SYS_unlinkat, dirfd, path, flags); 204 | ``` 205 | 206 | ### #define SYS_mkdirat 34 207 | 功能:创建目录; 208 | 209 | 输入: 210 | 211 | - dirfd:要创建的目录所在的目录的文件描述符。 212 | - path:要创建的目录的名称。如果path是相对路径,则它是相对于dirfd目录而言的。如果path是相对路径,且dirfd的值为AT_FDCWD,则它是相对于当前路径而言的。如果path是绝对路径,则dirfd被忽略。 213 | - mode:文件的所有权描述。详见`man 7 inode `。 214 | 215 | 返回值:成功执行,返回0。失败,返回-1。 216 | 217 | ``` 218 | int dirfd, const char *path, mode_t mode; 219 | int ret = syscall(SYS_mkdirat, dirfd, path, mode); 220 | ``` 221 | 222 | ### #define SYS_umount2 39 223 | * 功能:卸载文件系统; 224 | * 输入:指定卸载目录,卸载参数; 225 | * 返回值:成功返回0,失败返回-1; 226 | ``` 227 | const char *special, int flags; 228 | int ret = syscall(SYS_umount2, special, flags); 229 | ``` 230 | 231 | ### #define SYS_mount 40 232 | * 功能:挂载文件系统; 233 | * 输入: 234 | - special: 挂载设备; 235 | - dir: 挂载点; 236 | - fstype: 挂载的文件系统类型; 237 | - flags: 挂载参数; 238 | - data: 传递给文件系统的字符串参数,可为NULL; 239 | * 返回值:成功返回0,失败返回-1; 240 | ``` 241 | const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data; 242 | int ret = syscall(SYS_mount, special, dir, fstype, flags, data); 243 | ``` 244 | 245 | ### #define SYS_fstat 80 246 | * 功能:获取文件状态; 247 | * 输入: 248 | - fd: 文件句柄; 249 | - kst: 接收保存文件状态的指针; 250 | ``` 251 | struct kstat { 252 | dev_t st_dev; 253 | ino_t st_ino; 254 | mode_t st_mode; 255 | nlink_t st_nlink; 256 | uid_t st_uid; 257 | gid_t st_gid; 258 | dev_t st_rdev; 259 | unsigned long __pad; 260 | off_t st_size; 261 | blksize_t st_blksize; 262 | int __pad2; 263 | blkcnt_t st_blocks; 264 | long st_atime_sec; 265 | long st_atime_nsec; 266 | long st_mtime_sec; 267 | long st_mtime_nsec; 268 | long st_ctime_sec; 269 | long st_ctime_nsec; 270 | unsigned __unused[2]; 271 | }; 272 | ``` 273 | * 返回值:成功返回0,失败返回-1; 274 | ``` 275 | int fd; 276 | struct kstat kst; 277 | int ret = syscall(SYS_fstat, fd, &kst); 278 | ``` 279 | 280 | ## 进程管理相关 281 | 282 | ### #define SYS_clone 220 283 | * 功能:创建一个子进程; 284 | * 输入: 285 | - flags: 创建的标志,如SIGCHLD; 286 | - stack: 指定新进程的栈,可为0; 287 | - ptid: 父线程ID; 288 | - tls: TLS线程本地存储描述符; 289 | - ctid: 子线程ID; 290 | * 返回值:成功则返回子进程的线程ID,失败返回-1; 291 | ``` 292 | pid_t ret = syscall(SYS_clone, flags, stack, ptid, tls, ctid) 293 | ``` 294 | 295 | ### #define SYS_execve 221 296 | * 功能:执行一个指定的程序; 297 | * 输入: 298 | - path: 待执行程序路径名称, 299 | - argv: 程序的参数, 300 | - envp: 环境变量的数组指针 301 | * 返回值:成功不返回,失败返回-1; 302 | ``` 303 | const char *path, char *const argv[], char *const envp[]; 304 | int ret = syscall(SYS_execve, path, argv, envp); 305 | ``` 306 | 307 | ### #define SYS_wait4 260 308 | * 功能:等待进程改变状态; 309 | * 输入: 310 | - pid: 指定进程ID,可为-1等待任何子进程; 311 | - status: 接收状态的指针; 312 | - options: 选项:WNOHANG,WUNTRACED,WCONTINUED; 313 | * 返回值:成功则返回进程ID;如果指定了WNOHANG,且进程还未改变状态,直接返回0;失败则返回-1; 314 | ``` 315 | pid_t pid, int *status, int options; 316 | pid_t ret = syscall(SYS_wait4, pid, status, options); 317 | ``` 318 | 319 | ### #define SYS_exit 93 320 | * 功能:触发进程终止,无返回值; 321 | * 输入:终止状态值; 322 | * 返回值:无返回值; 323 | ``` 324 | int ec; 325 | syscall(SYS_exit, ec); 326 | ``` 327 | 328 | ### #define SYS_getppid 173 329 | * 功能:获取父进程ID; 330 | * 输入:系统调用ID; 331 | * 返回值:成功返回父进程ID; 332 | ``` 333 | pid_t ret = syscall(SYS_getppid); 334 | ``` 335 | 336 | ### #define SYS_getpid 172 337 | * 功能:获取进程ID; 338 | * 输入:系统调用ID; 339 | * 返回值:成功返回进程ID; 340 | ``` 341 | pid_t ret = syscall(SYS_getpid); 342 | ``` 343 | 344 | ## 内存管理相关 345 | ### #define SYS_brk 214 346 | * 功能:修改数据段的大小; 347 | * 输入:指定待修改的地址; 348 | * 返回值:成功返回0,失败返回-1; 349 | ``` 350 | uintptr_t brk; 351 | uintptr_t ret = syscall(SYS_brk, brk); 352 | ``` 353 | 354 | ### #define SYS_munmap 215 355 | * 功能:将文件或设备取消映射到内存中; 356 | * 输入:映射的指定地址及区间; 357 | * 返回值:成功返回0,失败返回-1; 358 | ``` 359 | void *start, size_t len 360 | int ret = syscall(SYS_munmap, start, len); 361 | ``` 362 | 363 | ### #define SYS_mmap 222 364 | * 功能:将文件或设备映射到内存中; 365 | * 输入: 366 | - start: 映射起始位置, 367 | - len: 长度, 368 | - prot: 映射的内存保护方式,可取:PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE 369 | - flags: 映射是否与其他进程共享的标志, 370 | - fd: 文件句柄, 371 | - off: 文件偏移量; 372 | * 返回值:成功返回已映射区域的指针,失败返回-1; 373 | ``` 374 | void *start, size_t len, int prot, int flags, int fd, off_t off 375 | long ret = syscall(SYS_mmap, start, len, prot, flags, fd, off); 376 | ``` 377 | 378 | ## 其他 379 | 380 | ### #define SYS_times 153 381 | * 功能:获取进程时间; 382 | * 输入:tms结构体指针,用于获取保存当前进程的运行时间数据; 383 | * 返回值:成功返回已经过去的滴答数,失败返回-1; 384 | ``` 385 | struct tms *tms; 386 | clock_t ret = syscall(SYS_times, tms); 387 | ``` 388 | 389 | ### #define SYS_uname 160 390 | * 功能:打印系统信息; 391 | * 输入:utsname结构体指针用于获得系统信息数据; 392 | * 返回值:成功返回0,失败返回-1; 393 | ``` 394 | struct utsname *uts; 395 | int ret = syscall(SYS_uname, uts); 396 | ``` 397 | ### #define SYS_sched_yield 124 398 | * 功能:让出调度器; 399 | * 输入:系统调用ID; 400 | * 返回值:成功返回0,失败返回-1; 401 | ``` 402 | int ret = syscall(SYS_sched_yield); 403 | ``` 404 | 405 | ### #define SYS_gettimeofday 169 406 | * 功能:获取时间; 407 | * 输入: timespec结构体指针用于获得时间值; 408 | * 返回值:成功返回0,失败返回-1; 409 | ``` 410 | struct timespec *ts; 411 | int ret = syscall(SYS_gettimeofday, ts, 0); 412 | ``` 413 | ### #define SYS_nanosleep 101 414 | * 功能:执行线程睡眠,sleep()库函数基于此系统调用; 415 | * 输入:睡眠的时间间隔; 416 | ``` 417 | struct timespec { 418 | time_t tv_sec; /* 秒 */ 419 | long tv_nsec; /* 纳秒, 范围在0~999999999 */ 420 | }; 421 | ``` 422 | * 返回值:成功返回0,失败返回-1; 423 | ``` 424 | const struct timespec *req, struct timespec *rem; 425 | int ret = syscall(SYS_nanosleep, req, rem); 426 | ``` 427 | 428 | 429 | ## 调用 430 | ``` 431 | static inline _u64 internal_syscall(long n, _u64 _a0, _u64 _a1, _u64 _a2, _u64 432 | _a3, _u64 _a4, _u64 _a5) { 433 | register _u64 a0 asm("a0") = _a0; 434 | register _u64 a1 asm("a1") = _a1; 435 | register _u64 a2 asm("a2") = _a2; 436 | register _u64 a3 asm("a3") = _a3; 437 | register _u64 a4 asm("a4") = _a4; 438 | register _u64 a5 asm("a5") = _a5; 439 | register long syscall_id asm("a7") = n; 440 | asm volatile ("ecall" : "+r"(a0) : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r" 441 | (a5), "r"(syscall_id)); 442 | return a0; 443 | } 444 | ``` 445 | -------------------------------------------------------------------------------- /doc/busybox/busybox.md: -------------------------------------------------------------------------------- 1 | # Busybox测试样例 2 | 3 | ## 题目描述 4 | 5 | BusyBox 是一个提供多种 Unix 工具的轻量级软件包,它将常见的 Unix 工具(如 `ls`、`cp`、`mv`、`sh`、`cat` 等)合并到一个可执行文件中。它旨在为嵌入式系统或资源受限环境提供简洁、高效的替代方案。通过这种方式,BusyBox 在占用少量存储空间的同时,能够提供丰富的功能,特别适合嵌入式设备、Linux 系统的救援模式或容器化环境中使用。对于轻量级内核来说,支持 busybox 就可以拥有了一个简单的交互终端功能。 6 | 7 | 8 | 9 | 本测试用例会将编译好的 busybox 文件作为输入的可执行文件,并为其传递一系列的参数,从而执行一系列功能,判断待测内核对 busybox 功能的支持情况。 10 | 11 | 12 | 13 | ## 编译方法 14 | 15 | - 源码地址:https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025/busybox 16 | - 编译 busybox 方式:参考 https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025 下的 README.md 对完整测例进行编译,在项目根目录下生成的 sdcard 目录下,会找到 busybox 目录,其即为编译生成的测例。 17 | - 单独编译:请修改 [编译目标](https://github.com/oscomp/testsuits-for-oskernel/blob/pre-2025/Makefile.sub#L14) ,仅保留 busybox 目标。之后按照 README 操作进行,即可单独编译 busybox 测例到 sdcard 目录下。 18 | 19 | 20 | 21 | ## 样例输出 22 | 23 | 24 | 测试 busybox musl 版本的输出可能如下所示: 25 | ``` 26 | #### OS COMP TEST GROUP START busybox-musl #### 27 | #### independent command test 28 | testcase busybox echo "#### independent command test" success 29 | testcase busybox ash -c exit success 30 | testcase busybox sh -c exit success 31 | bbb 32 | testcase busybox basename /aaa/bbb success 33 | February 2025 34 | Su Mo Tu We Th Fr Sa 35 | 1 36 | 2 3 4 5 6 7 8 37 | 9 10 11 12 13 14 15 38 | 16 17 18 19 20 21 22 39 | 23 24 25 26 27 28 40 | 41 | testcase busybox cal success 42 | 43 | 。。。 44 | testcase busybox echo "ccccccc" >> test.txt success 45 | testcase busybox echo "bbbbbbb" >> test.txt success 46 | testcase busybox echo "aaaaaaa" >> test.txt success 47 | testcase busybox echo "2222222" >> test.txt success 48 | testcase busybox echo "1111111" >> test.txt success 49 | testcase busybox echo "bbbbbbb" >> test.txt success 50 | testcase busybox sort test.txt | ./busybox uniq success 51 | File: test.txt 52 | Size: 60 Blocks: 8 IO Block: 4096 regular file 53 | Device: 10304h/66308d Inode: 101061027 Links: 1 54 | Access: (0664/-rw-rw-r--) Uid: ( 1010/ zyj) Gid: ( 1010/ zyj) 55 | Access: 2025-02-26 15:30:12.000000000 56 | Modify: 2025-02-26 15:30:12.000000000 57 | Change: 2025-02-26 15:30:12.000000000 58 | 59 | testcase busybox stat test.txt success 60 | hello world 61 | ccccccc 62 | bbbbbbb 63 | aaaaaaa 64 | 2222222 65 | 1111111 66 | bbbbbbb 67 | testcase busybox strings test.txt success 68 | 7 8 60 test.txt 69 | testcase busybox wc test.txt success 70 | testcase busybox [ -f test.txt ] success 71 | hello world 72 | ccccccc 73 | bbbbbbb 74 | aaaaaaa 75 | 2222222 76 | 1111111 77 | bbbbbbb 78 | testcase busybox more test.txt success 79 | testcase busybox rm test.txt success 80 | testcase busybox mkdir test_dir success 81 | testcase busybox mv test_dir test success 82 | testcase busybox rmdir test success 83 | echo "hello world" > test.txt 84 | grep hello busybox_cmd.txt 85 | testcase busybox grep hello busybox_cmd.txt success 86 | testcase busybox cp busybox_cmd.txt busybox_cmd.bak success 87 | testcase busybox rm busybox_cmd.bak success 88 | ./busybox_cmd.txt 89 | testcase busybox find -name "busybox_cmd.txt" success 90 | #### OS COMP TEST GROUP END busybox-musl #### 91 | ``` 92 | 93 | 用户可以将sdcard 中的 busybox_testcode.sh 文件中提到的 `./busybox` 字段修改为`busybox`字段,使用本机自带的 busybox 程序执行 `busybox sh busybox_testcode.sh`,也可得到如上输出。 94 | 95 | 观察 `busybox_testcode.sh`可以了解到,上述输出是`busybox_cmd.txt`中每一条指令的执行结果。待测脚本读取了 `busybox_cmd.txt` 的每一行,执行 `eval ./busybox $line` ,将这条指令进行执行,并依照返回值进行判断。 96 | 97 | - 假设原有的语句中不包含 `false` 字段,则认为这条指令是一条应当成功执行的语句。此时若返回值不为 0 ,则认为执行失败,则这条指令不得分,输出`testbase xx fail` 98 | - 其他情况下均认为得分。如`rm busybox_cmd.bak`是其中的一条指令,若输出了`testcase busybox rm busybox_cmd.bak success`说明该指令得分。 99 | 100 | ```shell 101 | #!/busybox sh 102 | 103 | ./busybox echo "#### OS COMP TEST GROUP START busybox-glibc ####" 104 | # RST=result.txt 105 | # if [ -f $RST ];then 106 | # rm $RST 107 | # fi 108 | # touch $RST 109 | 110 | # echo "If the CMD runs incorrectly, return value will put in $RST" > $RST 111 | # echo -e "Else nothing will put in $RST\n" >> $RST 112 | # echo "TEST START" >> $RST 113 | 114 | ./busybox cat ./busybox_cmd.txt | while read line 115 | do 116 | eval "./busybox $line" 117 | RTN=$? 118 | if [[ $RTN -ne 0 && $line != "false" ]] ;then 119 | echo "testcase busybox $line fail" 120 | # echo "return: $RTN, cmd: $line" >> $RST 121 | else 122 | echo "testcase busybox $line success" 123 | fi 124 | done 125 | 126 | # echo "TEST END" >> $RST 127 | ./busybox echo "#### OS COMP TEST GROUP END busybox-glibc ####" 128 | ``` 129 | 130 | ## 评分依据 131 | 132 | 每一条指令占一分,若输出了`testbase xx success`(xx为指令内容)则得一分,否则不得分。 -------------------------------------------------------------------------------- /doc/busybox/busybox_cmd.txt: -------------------------------------------------------------------------------- 1 | echo "#### independent command test" 2 | ash -c exit 3 | sh -c exit 4 | basename /aaa/bbb 5 | cal 6 | clear 7 | date 8 | df 9 | dirname /aaa/bbb 10 | dmesg 11 | du 12 | expr 1 + 1 13 | false 14 | true 15 | which ls 16 | uname 17 | uptime 18 | printf "abc\n" 19 | ps 20 | pwd 21 | free 22 | hwclock 23 | kill 10 24 | ls 25 | sleep 1 26 | echo "#### file opration test" 27 | touch test.txt 28 | echo "hello world" > test.txt 29 | cat test.txt 30 | cut -c 3 test.txt 31 | od test.txt 32 | head test.txt 33 | tail test.txt 34 | hexdump -C test.txt 35 | md5sum test.txt 36 | echo "ccccccc" >> test.txt 37 | echo "bbbbbbb" >> test.txt 38 | echo "aaaaaaa" >> test.txt 39 | echo "2222222" >> test.txt 40 | echo "1111111" >> test.txt 41 | echo "bbbbbbb" >> test.txt 42 | sort test.txt | ./busybox uniq 43 | stat test.txt 44 | strings test.txt 45 | wc test.txt 46 | [ -f test.txt ] 47 | more test.txt 48 | rm test.txt 49 | mkdir test_dir 50 | mv test_dir test 51 | rmdir test 52 | grep hello busybox_cmd.txt 53 | cp busybox_cmd.txt busybox_cmd.bak 54 | rm busybox_cmd.bak 55 | find -name "busybox_cmd.txt" 56 | -------------------------------------------------------------------------------- /doc/busybox/busybox_testcode.sh: -------------------------------------------------------------------------------- 1 | #!/busybox sh 2 | 3 | ./busybox echo "#### OS COMP TEST GROUP START busybox-glibc ####" 4 | # RST=result.txt 5 | # if [ -f $RST ];then 6 | # rm $RST 7 | # fi 8 | # touch $RST 9 | 10 | # echo "If the CMD runs incorrectly, return value will put in $RST" > $RST 11 | # echo -e "Else nothing will put in $RST\n" >> $RST 12 | # echo "TEST START" >> $RST 13 | 14 | ./busybox cat ./busybox_cmd.txt | while read line 15 | do 16 | eval "./busybox $line" 17 | RTN=$? 18 | if [[ $RTN -ne 0 && $line != "false" ]] ;then 19 | echo "testcase busybox $line fail" 20 | # echo "return: $RTN, cmd: $line" >> $RST 21 | else 22 | echo "testcase busybox $line success" 23 | fi 24 | done 25 | 26 | # echo "TEST END" >> $RST 27 | ./busybox echo "#### OS COMP TEST GROUP END busybox-glibc ####" 28 | -------------------------------------------------------------------------------- /doc/cyclictest/cyclictest.md: -------------------------------------------------------------------------------- 1 | # cyclictest 测试用例 2 | 3 | ## 题目描述 4 | 5 | cyclictest 是 rt-tests 中的一个高精度测试程序,通过测量任务被唤醒的延迟时间来测试内核的实时性。 6 | 7 | 本测例还会用到同属于 rt-tests 的 hackbench 程序,和 cyclictest 同时运行来进行压力测试。 8 | 9 | ### [测试脚本](https://github.com/oscomp/testsuits-for-oskernel/blob/pre-2025/scripts/cyclictest/cyclictest_testcode.sh) 10 | 11 | ```sh 12 | ./busybox echo "#### OS COMP TEST GROUP START cyclictest ####" 13 | 14 | run_cyclictest() { 15 | echo "====== cyclictest $1 begin ======" 16 | ./cyclictest $2 17 | if [ $? == 0 ]; then 18 | ans="success" 19 | else 20 | ans="fail" 21 | fi 22 | echo "====== cyclictest $1 end: $ans ======" 23 | } 24 | 25 | run_cyclictest NO_STRESS_P1 "-a -i 1000 -t1 -p99 -D 1s -q" 26 | run_cyclictest NO_STRESS_P8 "-a -i 1000 -t8 -p99 -D 1s -q" 27 | 28 | echo "====== start hackbench ======" 29 | ./hackbench -l 100000000 & 30 | hackbench_pid=$! 31 | 32 | sleep 1 33 | 34 | run_cyclictest STRESS_P1 "-a -i 1000 -t1 -p99 -D 1s -q" 35 | run_cyclictest STRESS_P8 "-a -i 1000 -t8 -p99 -D 1s -q" 36 | 37 | # Kill children in the parent process's interrupt processing, 38 | # so SIGINT is used instead of SIGKILL 39 | kill -2 $hackbench_pid 40 | if [ $? == 0 ]; then 41 | ans="success" 42 | else 43 | ans="fail, ignore STRESS result" 44 | fi 45 | sleep 1 46 | echo "====== kill hackbench: $ans ======" 47 | 48 | 49 | ./busybox echo "#### OS COMP TEST GROUP END cyclictest ####" 50 | ``` 51 | 52 | 运行参数说明: 53 | - `-a` 绑定测试线程到所有 CPU。 54 | - `-i 1000` 设置基准间隔为 1000 微秒 55 | - `-t1`/`-t8` 运行 1/8 个测试线程 56 | - `-p99` 设置线程优先级为 99 57 | - `-D 1s` 指定测试时长为 1s 58 | - `-q` 安静模式,只在退出时输出摘要信息 59 | 60 | ## 编译方法 61 | 62 | 请参考[赛题仓库](https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025)中的 `rt-tests-2.7` 目录和 `Makefile.sub` 中的 `cyclictest` 目标。 63 | 64 | ## 样例输出 65 | 66 | ``` 67 | #### OS COMP TEST GROUP START cyclictest #### 68 | ====== cyclictest NO_STRESS_P1 begin ====== 69 | # /dev/cpu_dma_latency set to 0us 70 | T: 0 (11312) P:99 I:1000 C: 1000 Min: 1 Act: 1 Avg: 1 Max: 8 71 | ====== cyclictest NO_STRESS_P1 end: success ====== 72 | ====== cyclictest NO_STRESS_P8 begin ====== 73 | # /dev/cpu_dma_latency set to 0us 74 | T: 0 (11315) P:99 I:1000 C: 1000 Min: 1 Act: 1 Avg: 1 Max: 8 75 | T: 1 (11316) P:99 I:1500 C: 667 Min: 1 Act: 1 Avg: 1 Max: 1 76 | T: 2 (11317) P:99 I:2000 C: 500 Min: 1 Act: 1 Avg: 1 Max: 2 77 | T: 3 (11318) P:99 I:2500 C: 400 Min: 1 Act: 1 Avg: 1 Max: 3 78 | T: 4 (11319) P:99 I:3000 C: 334 Min: 1 Act: 1 Avg: 1 Max: 49 79 | T: 5 (11320) P:99 I:3500 C: 286 Min: 1 Act: 1 Avg: 1 Max: 2 80 | T: 6 (11321) P:99 I:4000 C: 250 Min: 1 Act: 1 Avg: 1 Max: 2 81 | T: 7 (11322) P:99 I:4500 C: 223 Min: 1 Act: 1 Avg: 1 Max: 2 82 | ====== cyclictest NO_STRESS_P8 end: success ====== 83 | ====== start hackbench ====== 84 | Running in process mode with 10 groups using 40 file descriptors each (== 400 tasks) 85 | Each sender will pass 100000000 messages of 100 bytes 86 | ====== cyclictest STRESS_P1 begin ====== 87 | # /dev/cpu_dma_latency set to 0us 88 | T: 0 (11726) P:99 I:1000 C: 1000 Min: 2 Act: 2 Avg: 2 Max: 14 89 | ====== cyclictest STRESS_P1 end: success ====== 90 | ====== cyclictest STRESS_P8 begin ====== 91 | # /dev/cpu_dma_latency set to 0us 92 | T: 0 (11729) P:99 I:1000 C: 1000 Min: 1 Act: 2 Avg: 2 Max: 23 93 | T: 1 (11730) P:99 I:1500 C: 667 Min: 1 Act: 2 Avg: 2 Max: 7 94 | T: 2 (11731) P:99 I:2000 C: 500 Min: 1 Act: 2 Avg: 2 Max: 9 95 | T: 3 (11732) P:99 I:2500 C: 400 Min: 2 Act: 2 Avg: 2 Max: 5 96 | T: 4 (11733) P:99 I:3000 C: 334 Min: 1 Act: 2 Avg: 2 Max: 6 97 | T: 5 (11734) P:99 I:3500 C: 286 Min: 1 Act: 2 Avg: 2 Max: 16 98 | T: 6 (11735) P:99 I:4000 C: 250 Min: 2 Act: 3 Avg: 2 Max: 9 99 | T: 7 (11736) P:99 I:4500 C: 223 Min: 1 Act: 2 Avg: 2 Max: 7 100 | ====== cyclictest STRESS_P8 end: success ====== 101 | Signal 2 caught, longjmp'ing out! 102 | longjmp'ed out, reaping children 103 | sending SIGTERM to all child processes 104 | signaling 400 worker threads to terminate 105 | SENDER: write (error: Connection reset by peer) 106 | SENDER: write (error: Connection reset by peer) 107 | SENDER: write (error: Connection reset by peer) 108 | SENDER: write (error: Broken pipe) 109 | SENDER: write (error: Broken pipe) 110 | SENDER: write (error: Connection reset by peer) 111 | Time: 3.102 112 | ====== kill hackbench: success ====== 113 | #### OS COMP TEST GROUP END cyclictest #### 114 | ``` 115 | 116 | 与 BusyBox 测例类似地,可以通过修改测试脚本中的程序路径,在本机上执行此脚本得到以上输出,不过需要注意运行 `cyclictest` 需要 root 权限或加入 `realtime` 用户组。 117 | 118 | ## 评分依据 119 | 120 | 成功运行一次 cyclictest 应当输出形如 `cyclictest * end: success` 的内容,一共应当有 `NO_STRESS_P1` `NO_STRESS_P8` `STRESS_P1` `STRESS_P8` 四次输出。且如果没有输出 `kill hackbench: success`,对应 `STRESS_P1` `STRESS_P8` 的两个结果将会被舍弃。 121 | 122 | 根据 cyclictest 的输出,对内核的实时性也做一定的评分。 123 | -------------------------------------------------------------------------------- /doc/iperf/iperf.md: -------------------------------------------------------------------------------- 1 | ## 测试题目说明 2 | 3 | ### 1. 题目描述 4 | 5 | `iperf3` 是一个用于测量 TCP、UDP 和 SCTP 网络带宽的工具。在本测试中,学生将学习如何在 ArceOS 操作系统上编译和运行 `iperf3`,并使用该工具进行网络带宽的测试。此外,学生还需要理解如何修改 `iperf3` 的源代码,并在 ArceOS 上优化其性能。 6 | 7 | ### 2. 编译方法 8 | 9 | 在 ArceOS 上编译并运行 `iperf3` 服务器和客户端,按照以下步骤操作: 10 | 11 | #### 步骤 1:编译 `iperf3` 12 | 13 | 在 ArceOS 的根目录下,使用以下命令来编译和启动 `iperf3` 服务器: 14 | 15 | ```bash 16 | # 在 ArceOS 根目录下 17 | make A=apps/c/iperf BLK=y NET=y ARCH= run 18 | ``` 19 | 20 | - `A=apps/c/iperf`:指定 `iperf` 应用程序的路径。 21 | - `BLK=y` 和 `NET=y`:启用块设备和网络支持。 22 | - `ARCH=`:指定目标架构(如 `x86_64`)。 23 | 24 | #### 步骤 2:修改和构建代码(根据需要) 25 | 26 | 根据 `iperf.patch` 中的代码修改,修改 `iperf3` 源代码文件,并重新编译。 27 | 28 | 修改的部分包括: 29 | - 优化内存管理,使用 `malloc` 替代 `mmap` 来创建缓冲区。 30 | - 修复一些头文件和库的引用。 31 | - 修改 `iperf3` 的网络配置,包括禁用 `sched_setaffinity` 相关的代码,以便于 ArceOS 环境的兼容性。 32 | 33 | #### 步骤 3:运行 `iperf3` 服务器 34 | 35 | 在 ArceOS 上启动 `iperf3` 服务器: 36 | 37 | ```bash 38 | # 启动 iperf3 服务器 39 | iperf3 -s -p 5555 40 | ``` 41 | 42 | #### 步骤 4:运行 `iperf3` 客户端 43 | 44 | 在另一个终端或机器上运行 `iperf3` 客户端进行网络带宽测试: 45 | 46 | ```bash 47 | # 作为客户端运行 48 | iperf3 -c 127.0.0.1 -p 5555 49 | ``` 50 | 51 | ### 3. 样例输出 52 | 53 | 当 `iperf3` 在 ArceOS 上运行时,服务器和客户端的输出应如下所示: 54 | 55 | **服务器端输出:** 56 | 57 | ``` 58 | ----------------------------------------------------------- 59 | Server listening on 5555 60 | ----------------------------------------------------------- 61 | [ 5] local 0.0.0.0 port 5555 connected to 127.0.0.1 port 5555 62 | [ 5] 0.0-10.0 sec 1.23 GBytes 1.05 Gbits/sec 63 | ``` 64 | 65 | **客户端输出:** 66 | 67 | ``` 68 | ----------------------------------------------------------- 69 | Client connecting to 127.0.0.1, port 5555 70 | ----------------------------------------------------------- 71 | [ 5] local 127.0.0.1 port 54321 connected to 127.0.0.1 port 5555 72 | [ 5] 0.0-10.0 sec 1.23 GBytes 1.05 Gbits/sec 73 | ``` 74 | 75 | ### 4. 评分依据 76 | 77 | 评分将根据以下几个方面进行: 78 | 79 | - **正确性**:能否成功在 ArceOS 上编译并运行 `iperf3` 服务器和客户端。 80 | - **性能测试**:是否能够在 `iperf3` 中使用 TCP 和 UDP 模式进行网络带宽测试,并理解其输出结果。 81 | - **代码修改**:能否根据 `iperf.patch` 中的指示修改 `iperf3` 代码,包括内存管理和网络配置。 82 | - **理解与优化**:能否根据 `iperf3` 的参数优化网络带宽测试,如调整缓冲区大小和发送比特率等。 83 | - **异常处理**:能否处理测试过程中可能出现的错误,并进行适当的调试。 84 | 85 | 86 | -------------------------------------------------------------------------------- /doc/libcbench/libcbench.md: -------------------------------------------------------------------------------- 1 | 2 | ## 题目描述 3 | 4 | libc-bench 是一个用于测试和比较不同 C/POSIX 标准库函数实现的时间和内存效率的测试工具集。它由 Eta Labs 开发,主要用于评估标准库函数(如 malloc、字符串操作、线程创建等)的性能。 5 | 主要功能: 6 | - 内存分配性能测试:测量 malloc 在不同线程竞争条件下的吞吐量和开销,以及释放内存返回给操作系统的效率。 7 | - 字符串和正则表达式搜索:测试标准库中字符串操作和正则表达式匹配的性能。 8 | - 线程创建和销毁性能:评估线程创建和销毁的吞吐量。 9 | - UTF-8 解码性能:测试 UTF-8 编码的解码效率。 10 | - 标准 I/O 测试:测量标准输入输出缓冲读写性能。 11 | 12 | 13 | ## 编译方法 14 | 15 | - 源码地址:https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025/busybox 16 | - 编译 libcbench 方式:参考 https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025 下的 README.md 对完整测例进行编译,在项目根目录下生成的 sdcard 目录下,会找到 busybox 目录,其即为编译生成的测例。 17 | - 单独编译:请修改 [编译目标](https://github.com/oscomp/testsuits-for-oskernel/blob/pre-2025/Makefile.sub#L14) ,仅保留 libcbench 目标。之后按照 README 操作进行,即可单独编译 busybox 测例到 sdcard 目录下。 18 | 19 | ## 样例输出 20 | 21 | ```shell 22 | b_malloc_sparse (0) 23 | time: 0.044845625, virt: 39376, res: 0, dirty: 0 24 | 25 | b_malloc_bubble (0) 26 | time: 0.035995583, virt: 39376, res: 0, dirty: 0 27 | 28 | b_malloc_tiny1 (0) 29 | time: 0.007387947, virt: 628, res: 0, dirty: 0 30 | 31 | b_malloc_tiny2 (0) 32 | time: 0.004802770, virt: 628, res: 0, dirty: 0 33 | 34 | b_malloc_big1 (0) 35 | time: 0.010567392, virt: 80080, res: 0, dirty: 0 36 | 37 | b_malloc_big2 (0) 38 | time: 0.007766442, virt: 80080, res: 0, dirty: 0 39 | 40 | b_malloc_thread_stress (0) 41 | time: 0.091500541, virt: 72, res: 0, dirty: 0 42 | 43 | b_malloc_thread_local (0) 44 | time: 0.087201559, virt: 84, res: 0, dirty: 0 45 | 46 | b_string_strstr ("abcdefghijklmnopqrstuvwxyz") 47 | time: 0.018217474, virt: 0, res: 0, dirty: 0 48 | 49 | b_string_strstr ("azbycxdwevfugthsirjqkplomn") 50 | time: 0.025178139, virt: 0, res: 0, dirty: 0 51 | 52 | b_string_strstr ("aaaaaaaaaaaaaacccccccccccc") 53 | time: 0.017301663, virt: 0, res: 0, dirty: 0 54 | 55 | b_string_strstr ("aaaaaaaaaaaaaaaaaaaaaaaaac") 56 | time: 0.017933191, virt: 0, res: 0, dirty: 0 57 | 58 | b_string_strstr ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac") 59 | time: 0.020625649, virt: 0, res: 0, dirty: 0 60 | 61 | b_string_memset (0) 62 | time: 0.008373490, virt: 0, res: 0, dirty: 0 63 | 64 | b_string_strchr (0) 65 | time: 0.019126830, virt: 0, res: 0, dirty: 0 66 | 67 | b_string_strlen (0) 68 | time: 0.015457260, virt: 0, res: 0, dirty: 0 69 | 70 | b_pthread_createjoin_serial1 (0) 71 | time: 1.021888869, virt: 0, res: 0, dirty: 0 72 | 73 | b_pthread_createjoin_serial2 (0) 74 | time: 0.971511952, virt: 0, res: 0, dirty: 0 75 | 76 | b_pthread_create_serial1 (0) 77 | time: 0.937488568, virt: 50000, res: 0, dirty: 0 78 | 79 | b_pthread_uselesslock (0) 80 | time: 0.109982275, virt: 0, res: 0, dirty: 0 81 | 82 | b_utf8_bigbuf (0) 83 | time: 0.048280698, virt: 0, res: 0, dirty: 0 84 | 85 | b_utf8_onebyone (0) 86 | time: 0.183226514, virt: 0, res: 0, dirty: 0 87 | 88 | b_stdio_putcgetc (0) 89 | time: 0.369177917, virt: 4, res: 0, dirty: 0 90 | 91 | b_stdio_putcgetc_unlocked (0) 92 | time: 0.368543852, virt: 4, res: 0, dirty: 0 93 | 94 | b_regex_compile ("(a|b|c)*d*b") 95 | time: 0.085520989, virt: 20, res: 0, dirty: 0 96 | 97 | b_regex_search ("(a|b|c)*d*b") 98 | time: 0.097498578, virt: 20, res: 0, dirty: 0 99 | 100 | b_regex_search ("a{25}b") 101 | time: 0.296807894, virt: 20, res: 0, dirty: 0 102 | ``` 103 | 104 | ## 评分依据 105 | 106 | - time: 执行时间。执行时间越短,表示性能越好。 107 | - virt: 虚拟内存占用情况。通常,较低的内存占用表示更好的内存管理效率 108 | - res: 常驻内存占用情况。通常,较低的内存占用表示更好的内存管理效率 109 | - dirty: 脏页数量。较低的脏页数量通常意味着更少的磁盘 I/O 操作,从而提高性能。 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /doc/libcbench/libcbench_testcode.sh: -------------------------------------------------------------------------------- 1 | 2 | ./busybox echo "#### OS COMP TEST GROUP START libcbench-musl ####" 3 | ./libc-bench 4 | ./busybox echo "#### OS COMP TEST GROUP END libcbench-musl ####" -------------------------------------------------------------------------------- /doc/libctest.md: -------------------------------------------------------------------------------- 1 | # Libctest测试样例 2 | 3 | ## 题目描述 4 | 5 | libc-test 是一个用于测试 C 标准库(libc)功能和兼容性的测试套件。C 标准库是 C 语言程序开发中不可或缺的一部分,它提供了诸如输入输出、内存管理、字符串处理等基本功能。libc-test 通过一系列精心设计的测试用例,对 C 标准库的各个功能模块进行全面而细致的测试,以确保其在不同环境下的正确性和稳定性。 6 | 本测试用例会将编译好的 libc-test 可执行文件作为输入,运行其中的各种测试用例,包括静态测试和动态测试。通过执行这些测试用例并检查输出结果,来判断待测内核是否能够正确支持 C 标准库的各项功能,从而验证内核与 C 标准库之间的兼容性和稳定性。 7 | 8 | 9 | 10 | ## 编译方法 11 | 12 | - 源码地址:https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025/libc-test 13 | - 编译 libctest 方式:参考 https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025 下的 README.md 对完整测例进行编译,在项目根目录下生成的 sdcard 目录下,会找到 libctest 目录,其即为编译生成的测例。 14 | - 单独编译:请修改 [编译目标](https://github.com/oscomp/testsuits-for-oskernel/blob/pre-2025/Makefile.sub#L14) ,仅保留 libctest 目标。之后按照 README 操作进行,即可单独编译 libctest 测例到 sdcard 目录下。 15 | 16 | 17 | 18 | ## 样例输出 19 | 20 | 21 | 测试 libctest 的输出可能如下所示: 22 | ``` 23 | #### OS COMP TEST GROUP START libctest #### 24 | ========== START entry-static.exe argv ========== 25 | Pass! 26 | ========== END entry-static.exe argv ========== 27 | ========== START entry-static.exe basename ========== 28 | Pass! 29 | ========== END entry-static.exe basename ========== 30 | ··· 31 | #### OS COMP TEST GROUP END libctest #### 32 | ``` 33 | 34 | 首先由libctest_testcode.sh输出`#### OS COMP TEST GROUP START libctest ####`,随后运行./run-static.sh以及./run-dynamic.sh脚本进行测试,脚本中执行`./runtest.exe -w entry-static.exe argv`等指令以运行如上例中的argv、basename等测例并输出`Pass!`,最后再由libctest_testcode.sh输出对应的`#### OS COMP TEST GROUP END libctest ####`。 35 | 36 | 37 | 38 | ## 评分依据 39 | 40 | 每一个测例占一分,若输出了`Pass!`则得一分,否则不得分。 -------------------------------------------------------------------------------- /doc/lmbench.md: -------------------------------------------------------------------------------- 1 | #lmbench 测试说明 2 | 3 | 4 | ##1. 空系统调用操作延迟(微秒) 5 | 6 | 测试结果预期范围(越小越好): 0.0757 - 2.0 7 | 8 | 9 | ##2. 读系统调用延迟(微秒) 10 | 11 | 测试结果预期范围(越小越好): 0.1 - 2.2 12 | 13 | 14 | ##3. 写系统调用延迟(微秒) 15 | 16 | 测试结果预期范围(越小越好): 0.1 - 2.2 17 | 18 | ##4. stat系统调用延迟(微秒) 19 | 20 | 测试结果预期范围(越小越好): 0.5 - 2.1 21 | 22 | 23 | ##5. fstat系统调用延迟(微秒) 24 | 25 | 测试结果预期范围(越小越好): 0.15 - 2.0 26 | 27 | 28 | ##6. open系统调用 open 延迟(微秒) 29 | 30 | 测试结果预期范围(越小越好): 1.0 - 3.0 31 | 32 | ##7. select系统调用延迟(微秒) 33 | 34 | 测试结果预期范围(越小越好): 0.5 - 2.7 35 | 36 | ##8. 信号安装延迟(微秒) 37 | 38 | 测试结果预期范围(越小越好): 0.1 - 2.3 39 | 40 | ##9. 信号捕获延迟(微秒) 41 | 42 | 测试结果预期范围(越小越好): 0.8 - 2.0 43 | 44 | ##10. 信号保护延迟(微秒) 45 | 46 | 测试结果预期范围(越小越好): 0.3 - 2.5 47 | 48 | ##11. 管道延迟(微秒) 49 | 50 | 测试结果预期范围(越小越好): 4 - 20 51 | 52 | ##12. 进程 fork 延迟(微秒) 53 | 54 | 测试结果预期范围(越小越好): 94 - 200 55 | 56 | ##13. 进程 exec 延迟(微秒) 57 | 58 | 测试结果预期范围(越小越好): 101 - 300 59 | 60 | ##14. 进程 shell 延迟(微秒) 61 | 62 | 测试结果预期范围(越小越好): 300 - 2000 63 | 64 | ##15. 文件系统写入带宽(KB/秒) 65 | 66 | 测试结果预期范围(越大越好): 3000 - 200000 67 | 68 | ##16. 页面错误延迟(微秒) 69 | 70 | 测试结果预期范围(越小越好): 0.1 - 3.2 71 | 72 | ##17. mmap 延迟(微秒) 73 | 74 | 测试结果预期范围(越小越好): 0.3 - 10 75 | 76 | ##18. 管道带宽(KB/秒) 77 | 78 | 测试结果预期范围(越大越好): 1000 - 10000 79 | 80 | ##19. 文件系统延迟(每秒创建+删除次数) 81 | 82 | 测试结果预期范围(越大越好): 100000 - 300000 83 | 84 | ##20. 512k 文件读取速度(仅 I/O,MB/秒) 85 | 86 | 测试结果预期范围(越大越好): 0.5 - 2.0 87 | 88 | ##21. 512k 文件读取速度(打开至关闭,MB/秒) 89 | 90 | 测试结果预期范围(越大越好): 0.5 - 2.2 91 | 92 | ##22. 512k mmap 读取速度(mmaponly,MB/秒) 93 | 94 | 测试结果预期范围(越大越好): 0.5 - 3.0 95 | 96 | ##23. 512k mmap 读取速度(open2close,MB/秒) 97 | 98 | 测试结果预期范围(越大越好): 0.5 - 3.0 99 | 100 | ##24. 上下文切换延迟(微秒/96 进程时) 101 | 102 | 测试结果预期范围(越小越好): 1 - 5.0 103 | -------------------------------------------------------------------------------- /doc/ltp/ltp.md: -------------------------------------------------------------------------------- 1 | 以下是关于 Linux LTP (Linux Test Project) 的详细介绍,包括题目描述、编译方法、样例输出和评分依据,输出为 Markdown 格式的文档代码: 2 | markdown 3 | # Linux LTP (Linux Test Project) 详细介绍 4 | 5 | Linux LTP 是一个功能强大的测试工具,适用于内核开发者、系统管理员和嵌入式工程师。 6 | 7 | - 题目描述:详细介绍了 LTP 的背景、目标和测试范围。 8 | - 编译方法:提供了标准编译和交叉编译的步骤,适用于不同场景。 9 | - 样例输出:展示了运行 syscalls 测试的典型日志,包含成功、失败和不适用的情况。 10 | - 评分依据:定义了结果分类、计算方法和评估标准,符合 LTP 的实际使用逻辑。 11 | 12 | 13 | ## 1. 题目描述 14 | 15 | Linux Test Project (LTP) 是一个开源测试框架,旨在验证 Linux 内核及其相关功能的可靠性、健壮性和稳定性。LTP 由 SGI 发起,并由 IBM、Cisco、Fujitsu、SUSE、Red Hat、Oracle 等公司共同开发和维护。其主要目标是通过自动化测试用例,检测 Linux 系统的功能是否正常运行,发现潜在的缺陷或问题,并提升内核及系统库的质量。 16 | 17 | LTP 测试套件包含数千个测试用例,覆盖以下领域: 18 | - **系统调用 (Syscalls)**:测试 Linux 内核提供的各种系统调用的正确性。 19 | - **文件系统 (Filesystem)**:验证文件操作、权限管理等功能的稳定性。 20 | - **网络 (Network)**:检查网络协议栈和相关功能的表现。 21 | - **内存管理 (Memory Management)**:测试内存分配、释放及压力条件下的表现。 22 | - **调度器 (Scheduler)**:验证任务调度和多线程行为的正确性。 23 | - **设备驱动 (Device Drivers)**:针对嵌入式设备扩展测试(例如 LTP-DDT)。 24 | 25 | LTP 的测试用例通常以 C 语言或 Shell 脚本编写,每个测试用例专注于某个特定功能点,输出结果为成功 (PASS)、失败 (FAIL) 或未实现/不适用 (TCONF)。 26 | 27 | --- 28 | 29 | ## 2. 编译方法 30 | 31 | LTP 的编译需要准备一个合适的 Linux 环境,并安装必要的依赖工具。以下是详细的编译步骤: 32 | 33 | ### 2.1 环境准备 34 | - **操作系统**:任意 Linux 发行版(如 Ubuntu、CentOS)。 35 | - **依赖工具**: 36 | - `git`:用于克隆 LTP 源码。 37 | - `gcc`:C 语言编译器。 38 | - `make`:构建工具。 39 | - `autoconf`、`automake`、`m4`:生成配置脚本。 40 | - `libc-dev`、`kernel-headers`:提供必要的头文件。 41 | 42 | 在 Ubuntu 上安装依赖的示例命令: 43 | ```bash 44 | sudo apt-get update 45 | sudo apt-get install git gcc make autoconf automake m4 build-essential linux-headers-$(uname -r) 46 | 2.2 下载源码 47 | 从 GitHub 克隆 LTP 的最新源码: 48 | bash 49 | git clone https://github.com/linux-test-project/ltp.git 50 | cd ltp 51 | 2.3 配置与编译 52 | 生成配置脚本: 53 | bash 54 | make autotools 55 | 此步骤生成 configure 文件。 56 | 配置编译选项: 57 | bash 58 | ./configure 59 | 可选参数: 60 | --prefix=/custom/path:指定安装路径,默认是 /opt/ltp。 61 | --target=arm-linux-gnueabihf:交叉编译到其他架构(如 ARM)。 62 | 编译源码: 63 | bash 64 | make 65 | 此步骤编译所有测试用例和工具。 66 | 安装: 67 | bash 68 | sudo make install 69 | 安装完成后,默认路径为 /opt/ltp,包含 bin、testcases、runtest 等目录。 70 | 2.4 交叉编译(可选) 71 | 对于嵌入式设备(如 ARM 架构),需使用交叉编译工具链: 72 | bash 73 | ./configure --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc 74 | make 75 | 3. 样例输出 76 | 运行 LTP 测试时,通常使用 runltp 脚本执行测试套件。以下是一个简单的运行示例及其输出。 77 | 3.1 运行命令 78 | 测试系统调用相关的用例: 79 | bash 80 | cd /opt/ltp 81 | ./runltp -f syscalls -p -l result.log -o output.log 82 | -f syscalls:指定运行 runtest/syscalls 中的测试用例。 83 | -p:生成详细的解析日志。 84 | -l result.log:记录结果日志。 85 | -o output.log:记录详细输出。 86 | 3.2 样例输出 87 | output.log 示例: 88 | TAG: fork01 89 | START: fork01 2025-04-04 15:00:00 90 | DURATION: 2 91 | STATUS: PASS 92 | OUTPUT: 93 | fork01 1 PASS Process forked successfully, PID: 12345 94 | 95 | TAG: open02 96 | START: open02 2025-04-04 15:00:02 97 | DURATION: 1 98 | STATUS: FAIL 99 | OUTPUT: 100 | open02 1 FAIL Failed to open file: Permission denied 101 | 102 | TAG: mmap03 103 | START: mmap03 2025-04-04 15:00:03 104 | DURATION: 3 105 | STATUS: TCONF 106 | OUTPUT: 107 | mmap03 1 TCONF Feature not supported on this kernel version 108 | result.log 示例: 109 | ``` 110 | Test Start Time: Fri Apr 04 15:00:00 2025 111 | Testcase Result Exit Value 112 | fork01 PASS 0 113 | open02 FAIL 1 114 | mmap03 TCONF 32 115 | Total Tests: 3 116 | Passed: 1 117 | Failed: 1 118 | Not Supported: 1 119 | 120 | ### 3.3 输出解释 121 | - **PASS**:测试用例成功通过。 122 | - **FAIL**:测试用例失败,可能表示内核 bug 或环境配置问题。 123 | - **TCONF**:测试用例不适用于当前系统(如缺少功能支持)。 124 | 125 | --- 126 | 127 | ## 4. 评分依据 128 | 129 | LTP 的评分依据主要基于测试用例的执行结果,旨在评估系统的功能正确性和稳定性。以下是评分的核心标准: 130 | 131 | ### 4.1 测试结果分类 132 | - **PASS (通过)**: 133 | - 测试用例按预期执行,功能正常,返回值为 0。 134 | - 评分:100%(该用例满分)。 135 | - **FAIL (失败)**: 136 | - 测试未按预期执行,可能由于内核 bug、权限问题或硬件限制。 137 | - 评分:0%(该用例不得分)。 138 | - **TCONF (不适用)**: 139 | - 测试用例因系统不支持相关功能而跳过(如旧内核版本)。 140 | - 评分:不计入总分。 141 | - **BROK (中断)**: 142 | - 测试因外部因素(如资源不足)中断。 143 | - 评分:视情况分析,通常不计入总分。 144 | 145 | ### 4.2 总体评分计算 146 | - **通过率** = (通过的测试用例数 / 总测试用例数) × 100%。 147 | - 示例: 148 | - 总用例:100 149 | - PASS:80,FAIL:10,TCONF:10 150 | - 通过率 = (80 / (100 - 10)) × 100% = 88.89% 151 | 152 | ### 4.3 评估标准 153 | - **功能覆盖**:测试用例是否覆盖了目标功能的所有关键点。 154 | - **稳定性**:在压力测试(如高负载、并发)下是否仍然通过。 155 | - **可重复性**:多次运行结果是否一致。 156 | - **错误信息**:失败用例是否提供清晰的诊断信息,便于定位问题。 157 | 158 | ### 4.4 注意事项 159 | - LTP 不是基准测试工具(benchmark),不直接衡量性能,而是关注功能验证。 160 | - 测试结果受环境影响(如内核版本、硬件配置),需结合具体上下文分析。 161 | 162 | --- 163 | 164 | -------------------------------------------------------------------------------- /doc/lua/lua.md: -------------------------------------------------------------------------------- 1 | # Lua 测试用例 2 | 3 | ## 题目描述 4 | 5 | Lua 是一种轻量级的、快速的脚本语言,常用于嵌入式编程和扩展应用程序。它的设计目标是简单、灵活并且易于嵌入其他应用程序中。本测试用例会将编译好的 lua 解释器作为输入的可执行文件,并且传入一系列的 lua 脚本文件,要求你运行这些脚本文件并输出结果,判断待测内核是否支持 lua 脚本的解释执行。 6 | 7 | 8 | ## 编译方法 9 | 10 | - 源码地址:https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025/lua 11 | - 编译 lua 方式:参考 https://github.com/oscomp/testsuits-for-oskernel/tree/pre-2025 下的 README.md 对完整测例进行编译,在项目根目录下生成的 sdcard 目录下,会找到 lua 目录,其即为编译生成的测例。 12 | - 单独编译:请修改 [编译目标](https://github.com/oscomp/testsuits-for-oskernel/blob/pre-2025/Makefile.sub#L14) ,仅保留 lua 目标。之后按照 README 操作进行,即可单独编译 lua 测例到 sdcard 目录下。 13 | 14 | 15 | 16 | ## 样例输出 17 | 18 | 测试 lua musl 的输出可能如下所示: 19 | ``` 20 | #### OS COMP TEST GROUP START lua-musl #### 21 | testcase lua date.lua success 22 | testcase lua file_io.lua success 23 | testcase lua max_min.lua success 24 | testcase lua random.lua success 25 | testcase lua remove.lua success 26 | testcase lua round_num.lua success 27 | testcase lua sin30.lua success 28 | testcase lua sort.lua success 29 | testcase lua strings.lua success 30 | #### OS COMP TEST GROUP END lua-musl #### 31 | ``` 32 | 33 | `lua_testcode.sh` 指定了测试所用到的各种 lua 脚本文件。`lua_testcode.sh` 将脚本文件作为参数传递给 `test.sh`,`test.sh` 会将脚本文件作为输入传递给 lua 解释器,并判断执行结束之后的返回值是否为 0。若为 0,则输出 `success`,否则输出 `fail`。 34 | 35 | 36 | ## 评分依据 37 | 38 | 参考[评分脚本](../../judge/judge_lua.py)可知,每一个测试用例占 1 分。当输出了 `success` 时,得 1 分;否则得 0 分。 -------------------------------------------------------------------------------- /doc/lua/lua_testcode.sh: -------------------------------------------------------------------------------- 1 | ./busybox echo "#### OS COMP TEST GROUP START lua-musl ####" 2 | 3 | ./test.sh date.lua 4 | ./test.sh file_io.lua 5 | ./test.sh max_min.lua 6 | ./test.sh random.lua 7 | ./test.sh remove.lua 8 | ./test.sh round_num.lua 9 | ./test.sh sin30.lua 10 | ./test.sh sort.lua 11 | ./test.sh strings.lua 12 | 13 | ./busybox echo "#### OS COMP TEST GROUP END lua-musl ####" 14 | -------------------------------------------------------------------------------- /doc/lua/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/busybox sh 2 | 3 | ./lua $1 4 | if [ $? == 0 ]; then 5 | echo "testcase lua $1 success" 6 | else 7 | echo "testcase lua $1 fail" 8 | fi 9 | -------------------------------------------------------------------------------- /judge/README.md: -------------------------------------------------------------------------------- 1 | 2 | 此目录为自动评测脚本。 3 | 4 | 评测系统当读取到输出包含 `#### OS COMP TEST GROUP START xxxxx ####` 和 `#### OS COMP TEST GROUP END xxxxx ####` 两行文本时,会自动找到judge/judge_xxxxx.py运行,即此目录中脚本的命名应与xxxxx_testcode.sh中输出的内容相对应。 5 | 6 | 评测机捕获到上述两行文本时,会将此两行中间的所有文本以stdin的方式传输给评测脚本,评测脚本需要分析文本内容,并以json格式给出评分结果。评分结果格式如下例所示: 7 | ```json 8 | [{"name": "test_brk", "all": 3, "pass": 3, "score": 3}, {"name": "test_chdir", "all": 3, "pass": 3, "score": 3}] 9 | ``` 10 | 输出结果为一个列表,列表中每一项为此题目中每一个测试点的得分情况。每一项测试点至少应包含`name`和`score`两个值,表示此测试点的名称和得分。对于通过性测试点,还可包含`all`字段表示本测试点共有多少分,`pass`表示通过多少个测试点。对于性能性测试点,还可以包含`result`表示本次提交匹配到的原始值,`baseline`表示一个参考基线值。除`name`和`score`外,`all`、`pass`、`result`和`baseline`均为可选项,评测系统仅将这些信息展示给学生,不参与评分过程。 11 | 12 | 请注意,学生提交的OS并非每次都能给出完整的题目输出,若输出信息中缺失了某些测试点,那么评测脚本也应该输出这些测试点,但得分为0。极端情况下,学生没有运行此测试题目,那么评测机会启动相应评测脚本,并直接发送EOF,评测脚本也应该输出包含所有测试点的JSON列表,其中所有得分均为0。 -------------------------------------------------------------------------------- /judge/judge_basic.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | from typing import List 4 | import re 5 | 6 | 7 | class TestBase: 8 | class AssertFail(RuntimeError): 9 | pass 10 | 11 | def __init__(self, name, count): 12 | self.name = "test_" + name 13 | self.count = count 14 | self.result = [] 15 | 16 | def test(self, data): 17 | pass 18 | 19 | def assert_util(self, func, rep, msg, *args): 20 | self.result.append({ 21 | "rep": rep, 22 | "res": func(*args), 23 | "arg": args, 24 | "msg": msg 25 | }) 26 | if not self.result[-1]["res"]: 27 | raise self.AssertFail() 28 | 29 | def assert_equal(self, v1, v2, msg=''): 30 | self.assert_util(lambda a, b: a == b, "=", msg, v1, v2) 31 | 32 | def assert_not_equal(self, v1, v2, msg=''): 33 | self.assert_util(lambda a, b: a != b, "!=", msg, v1, v2) 34 | 35 | def assert_great(self, v1, v2, msg=''): 36 | self.assert_util(lambda a, b: a > b, ">", msg, v1, v2) 37 | 38 | def assert_ge(self, v1, v2, msg=''): 39 | self.assert_util(lambda a, b: a >= b, ">=", msg, v1, v2) 40 | 41 | def assert_in_str(self, v1, v2, msg=''): 42 | def _fun(a: str, b: List[str]): 43 | pattern = re.compile(a) 44 | for line in b: 45 | if re.search(pattern, line) is not None: 46 | return True 47 | return False 48 | self.assert_util(_fun, "in", msg, v1, v2) 49 | 50 | def assert_in(self, v1, v2, msg=''): 51 | self.assert_util(lambda a, b: a in b, "in", msg, v1, v2) 52 | 53 | def start(self, data): 54 | self.result = [] 55 | try: 56 | self.test(data) 57 | except Exception: 58 | pass 59 | 60 | def get_result(self): 61 | return { 62 | "name": self.name, 63 | # "results": self.result, 64 | "all": self.count, 65 | "pass": len([x for x in self.result if x['res']]), 66 | "score": len([x for x in self.result if x['res']]), 67 | } 68 | 69 | 70 | 71 | 72 | 73 | class test_brk(TestBase): 74 | def __init__(self): 75 | super().__init__("brk", 3) 76 | 77 | def test(self, data): 78 | self.assert_ge(len(data), 3) 79 | p1 = "Before alloc,heap pos: (.+)" 80 | p2 = "After alloc,heap pos: (.+)" 81 | p3 = "Alloc again,heap pos: (.+)" 82 | line1 = re.findall(p1, data[0]) 83 | line2 = re.findall(p2, data[1]) 84 | line3 = re.findall(p3, data[2]) 85 | if line1 == [] or line2 == [] or line3 == []: 86 | return 87 | a1 = int(line1[0], 10) 88 | a2 = int(line2[0], 10) 89 | a3 = int(line3[0], 10) 90 | self.assert_equal(a1 + 64, a2) 91 | self.assert_equal(a2 + 64, a3) 92 | 93 | 94 | 95 | class test_chdir(TestBase): 96 | def __init__(self): 97 | super().__init__("chdir", 3) 98 | 99 | def test(self, data): 100 | self.assert_ge(len(data), 2) 101 | p1 = r"chdir ret: (\d)+" 102 | r1 = re.findall(p1, data[0]) 103 | if r1: 104 | self.assert_equal(r1[0], "0") 105 | self.assert_in("test_chdir", data[1]) 106 | 107 | 108 | 109 | class test_clone(TestBase): 110 | def __init__(self): 111 | super().__init__("clone", 4) 112 | 113 | def test(self, data): 114 | self.assert_ge(len(data), 3) 115 | self.assert_in_str(" Child says successfully!", data) 116 | self.assert_in_str(r"pid:\d+", data) 117 | self.assert_in_str("clone process successfully.", data) 118 | 119 | 120 | 121 | class test_close(TestBase): 122 | def __init__(self): 123 | super().__init__("close", 2) 124 | 125 | def test(self, data): 126 | self.assert_ge(len(data), 1) 127 | self.assert_in_str(r" close \d+ success.", data) 128 | 129 | 130 | 131 | class dup2_test(TestBase): 132 | def __init__(self): 133 | super().__init__("dup2", 2) 134 | 135 | def test(self, data): 136 | self.assert_ge(len(data), 1) 137 | self.assert_equal(" from fd 100", data[0]) 138 | 139 | 140 | 141 | class test_dup(TestBase): 142 | def __init__(self): 143 | super().__init__("dup", 2) 144 | 145 | def test(self, data): 146 | self.assert_ge(len(data), 1) 147 | res = re.findall(r" new fd is (\d+).", data[0]) 148 | if res: 149 | new_fd = int(res[0]) 150 | self.assert_not_equal(new_fd, 1) 151 | 152 | 153 | 154 | class test_execve(TestBase): 155 | def __init__(self): 156 | super().__init__("execve", 3) 157 | 158 | def test(self, data): 159 | self.assert_ge(len(data), 2) 160 | self.assert_equal(" I am test_echo.", data[0]) 161 | self.assert_equal("execve success.", data[1]) 162 | 163 | 164 | 165 | class test_exit(TestBase): 166 | def __init__(self): 167 | super().__init__("exit", 2) 168 | 169 | def test(self, data): 170 | self.assert_ge(len(data), 1) 171 | self.assert_equal("exit OK.", data[0]) 172 | 173 | 174 | 175 | class test_fork(TestBase): 176 | def __init__(self): 177 | super().__init__("fork", 3) 178 | 179 | def test(self, data): 180 | self.assert_ge(len(data), 2) 181 | self.assert_in_str(r" parent process\. wstatus:\d+", data) 182 | self.assert_in_str(" child process", data) 183 | 184 | 185 | 186 | class test_fstat(TestBase): 187 | def __init__(self): 188 | super().__init__("fstat", 3) 189 | 190 | def test(self, data): 191 | self.assert_ge(len(data), 2) 192 | res = re.findall(r"fstat ret: (\d+)", data[0]) 193 | if res: 194 | self.assert_equal(res[0], "0") 195 | res = re.findall(r"fstat: dev: \d+, inode: \d+, mode: (\d+), nlink: (\d+), size: \d+, atime: \d+, mtime: \d+, ctime: \d+", data[1]) 196 | if res: 197 | self.assert_equal(res[0][1], "1") 198 | 199 | 200 | 201 | class test_getcwd(TestBase): 202 | def __init__(self): 203 | super().__init__("getcwd", 2) 204 | 205 | def test(self, data): 206 | self.assert_ge(len(data), 1) 207 | self.assert_in_str("getcwd: (.+) successfully!", data) 208 | 209 | 210 | 211 | class test_getdents(TestBase): 212 | def __init__(self): 213 | super().__init__("getdents", 5) 214 | 215 | def test(self, data): 216 | self.assert_ge(len(data), 4) 217 | r = re.findall(r"open fd:(\d+)", data[0]) 218 | if r: 219 | self.assert_great(int(r[0]), 1) 220 | r = re.findall(r"getdents fd:(\d+)", data[1]) 221 | if r: 222 | self.assert_great(int(r[0]), 1) 223 | self.assert_equal("getdents success.", data[2]) 224 | self.assert_ge(len(data[3]), 1) 225 | 226 | 227 | 228 | 229 | class test_getpid(TestBase): 230 | def __init__(self): 231 | super().__init__("getpid", 3) 232 | 233 | def test(self, data): 234 | self.assert_ge(len(data), 2) 235 | self.assert_equal(data[0], "getpid success.") 236 | r = re.findall(r"pid = (\d+)", data[1]) 237 | if r: 238 | self.assert_great(int(r[0]), 0) 239 | 240 | 241 | 242 | class test_getppid(TestBase): 243 | def __init__(self): 244 | super().__init__("getppid", 2) 245 | 246 | def test(self, data): 247 | self.assert_ge(len(data), 1) 248 | self.assert_in(" getppid success. ppid : ", data[0]) 249 | 250 | 251 | 252 | 253 | class test_gettimeofday(TestBase): 254 | def __init__(self): 255 | super().__init__("gettimeofday", 3) 256 | 257 | def test(self, data): 258 | self.assert_ge(len(data), 3) 259 | self.assert_equal("gettimeofday success.", data[0]) 260 | res = re.findall(r"interval: (\d+)", data[2]) 261 | if res: 262 | self.assert_great(int(res[0]), 0) 263 | 264 | 265 | 266 | class test_mkdir(TestBase): 267 | def __init__(self): 268 | super().__init__("mkdir", 3) 269 | 270 | def test(self, data): 271 | self.assert_ge(len(data), 2) 272 | self.assert_in("mkdir ret:", data[0]) 273 | self.assert_in(" mkdir success.", data[1]) 274 | 275 | 276 | 277 | 278 | class test_mmap(TestBase): 279 | def __init__(self): 280 | super().__init__("mmap", 3) 281 | 282 | def test(self, data): 283 | self.assert_ge(len(data), 2) 284 | r = re.findall(r"file len: (\d+)", data[0]) 285 | if r: 286 | self.assert_ge(int(r[0]), 27) 287 | self.assert_equal("mmap content: Hello, mmap successfully!", data[1]) 288 | 289 | 290 | 291 | 292 | 293 | class test_mount(TestBase): 294 | def __init__(self): 295 | super().__init__("mount", 5) 296 | 297 | def test(self, data): 298 | self.assert_ge(len(data), 4) 299 | r = re.findall(r"Mounting dev:(.+) to ./mnt", data[0]) 300 | self.assert_equal(len(r) > 0, True) 301 | self.assert_equal(data[1], "mount return: 0") 302 | self.assert_equal(data[2], "mount successfully") 303 | self.assert_equal(data[3], "umount return: 0") 304 | 305 | 306 | 307 | 308 | 309 | class test_munmap(TestBase): 310 | def __init__(self): 311 | super().__init__("munmap", 4) 312 | 313 | def test(self, data): 314 | self.assert_ge(len(data), 3) 315 | r = re.findall(r"file len: (\d+)", data[0]) 316 | if r: 317 | self.assert_ge(int(r[0]), 27) 318 | self.assert_equal(data[1], "munmap return: 0") 319 | self.assert_equal(data[2], "munmap successfully!") 320 | 321 | 322 | 323 | 324 | 325 | class test_open(TestBase): 326 | def __init__(self): 327 | super().__init__("open", 3) 328 | 329 | def test(self, data): 330 | self.assert_ge(len(data), 2) 331 | self.assert_equal("Hi, this is a text file.", data[0]) 332 | self.assert_equal("syscalls testing success!", data[1]) 333 | 334 | 335 | 336 | 337 | 338 | 339 | class test_openat(TestBase): 340 | def __init__(self): 341 | super().__init__("openat", 4) 342 | 343 | def test(self, data): 344 | self.assert_ge(len(data), 3) 345 | r = re.findall(r"open dir fd: (\d+)", data[0]) 346 | if r: 347 | self.assert_great(int(r[0]), 1) 348 | r1 = re.findall(r"openat fd: (\d+)", data[1]) 349 | if r1: 350 | self.assert_great(int(r1[0]), int(r[0])) 351 | self.assert_equal(data[2], "openat success.") 352 | 353 | 354 | 355 | 356 | 357 | 358 | class test_pipe(TestBase): 359 | def __init__(self): 360 | super().__init__("pipe", 4) 361 | 362 | def test(self, data): 363 | self.assert_ge(len(data), 3) 364 | cpid0 = False 365 | cpid1 = False 366 | for line in data[:3]: 367 | if line == "cpid: 0": 368 | cpid0 = True 369 | continue 370 | r = re.findall(r"cpid: (\d+)", line) 371 | if r and int(r[0]) > 0: 372 | cpid1 = True 373 | continue 374 | self.assert_equal(cpid0, True) 375 | self.assert_equal(cpid1, True) 376 | self.assert_equal(data[2], " Write to pipe successfully.") 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | class test_read(TestBase): 386 | def __init__(self): 387 | super().__init__("read", 3) 388 | 389 | def test(self, data): 390 | self.assert_ge(len(data), 2) 391 | self.assert_equal("Hi, this is a text file.", data[0]) 392 | self.assert_equal("syscalls testing success!", data[1]) 393 | 394 | 395 | 396 | 397 | 398 | 399 | class test_sleep(TestBase): 400 | def __init__(self): 401 | super().__init__("sleep", 2) 402 | 403 | def test(self, data): 404 | self.assert_ge(len(data), 1) 405 | self.assert_equal(data[0], "sleep success.") 406 | 407 | 408 | 409 | 410 | 411 | 412 | class test_times(TestBase): 413 | def __init__(self): 414 | super().__init__("times", 6) 415 | 416 | def test(self, data): 417 | self.assert_ge(len(data), 2) 418 | self.assert_equal(data[0], "mytimes success") 419 | r = re.findall(r"\{tms_utime:(.+), tms_stime:(.+), tms_cutime:(.+), tms_cstime:(.+)}", data[1]) 420 | if r: 421 | self.assert_ge(int(r[0][0]), 0) 422 | self.assert_ge(int(r[0][1]), 0) 423 | self.assert_ge(int(r[0][2]), 0) 424 | self.assert_ge(int(r[0][3]), 0) 425 | 426 | 427 | 428 | 429 | 430 | class test_umount(TestBase): 431 | def __init__(self): 432 | super().__init__("umount", 5) 433 | 434 | def test(self, data): 435 | self.assert_ge(len(data), 4) 436 | # self.assert_equal(data[0], "Mounting dev:/dev/vda2 to ./mnt") 437 | r = re.findall(r"Mounting dev:(.+) to ./mnt", data[0]) 438 | self.assert_equal(len(r) > 0, True) 439 | self.assert_equal("mount return: 0", data[1]) 440 | self.assert_equal("umount success.", data[2]) 441 | self.assert_equal("return: 0", data[3]) 442 | 443 | 444 | 445 | 446 | 447 | class test_uname(TestBase): 448 | def __init__(self): 449 | super().__init__("uname", 2) 450 | 451 | def test(self, data): 452 | self.assert_ge(len(data), 1) 453 | self.assert_in("Uname: ", data[0]) 454 | 455 | 456 | 457 | 458 | class test_unlink(TestBase): 459 | def __init__(self): 460 | super().__init__("unlink", 2) 461 | 462 | def test(self, data): 463 | self.assert_ge(len(data), 1) 464 | self.assert_equal(data[0], " unlink success!") 465 | 466 | 467 | class test_wait(TestBase): 468 | def __init__(self): 469 | super().__init__("wait", 4) 470 | 471 | def test(self, data): 472 | self.assert_ge(len(data), 3) 473 | self.assert_equal(data[0], "This is child process") 474 | self.assert_equal(data[1], "wait child success.") 475 | self.assert_equal(data[2], "wstatus: 0") 476 | 477 | 478 | 479 | 480 | 481 | 482 | class test_waitpid(TestBase): 483 | def __init__(self): 484 | super().__init__("waitpid", 4) 485 | 486 | def test(self, data): 487 | self.assert_ge(len(data), 3) 488 | self.assert_equal(data[0], "This is child process") 489 | self.assert_equal(data[1], "waitpid successfully.") 490 | self.assert_equal(data[2], "wstatus: 3") 491 | 492 | 493 | 494 | 495 | class test_write(TestBase): 496 | def __init__(self): 497 | super().__init__("write", 2) 498 | 499 | def test(self, data): 500 | self.assert_ge(len(data), 1) 501 | self.assert_equal(data[0], "Hello operating system contest.") 502 | 503 | 504 | 505 | 506 | 507 | class test_yield(TestBase): 508 | def __init__(self): 509 | super().__init__("yield", 4) 510 | 511 | def test(self, data): 512 | self.assert_equal(len(data), 15) 513 | lst = ''.join(data) 514 | cnt = {'0': 0, '1': 0, '2': 0, '3': 0, '4': 0} 515 | for c in lst: 516 | if c not in ('0', '1', '2', '3', '4'): 517 | continue 518 | cnt[c] += 1 519 | self.assert_ge(cnt['0'], 3) 520 | self.assert_ge(cnt['1'], 3) 521 | self.assert_ge(cnt['2'], 3) 522 | 523 | 524 | 525 | # BBBBBBBBBB [1/5] 526 | # CCCCCCCCCC [1/5] 527 | # BBBBBBBBBB [2/5] 528 | # CCCCCCCCCC [2/5] 529 | # AAAAAAAAAA [1/5] 530 | # CCCCCCCCCC [3/5] 531 | # BBBBBBBBBB [3/5] 532 | # AAAAAAAAAA [2/5] 533 | # BBBBBBBBBB [4/5] 534 | # CCCCCCCCCC [4/5] 535 | # AAAAAAAAAA [3/5] 536 | # BBBBBBBBBB [5/5] 537 | # CCCCCCCCCC [5/5] 538 | # AAAAAAAAAA [4/5] 539 | # AAAAAAAAAA [5/5] 540 | 541 | 542 | tests = [x for x in TestBase.__subclasses__()] 543 | 544 | runner = {x.__name__: x() for x in tests} 545 | print(runner.keys(), file=sys.stderr) 546 | 547 | def get_runner(name): 548 | # return runner.get(name, runner.get("test_"+name, runner[name+"_test"])) 549 | return runner.get(name, None) 550 | # print(runner) 551 | 552 | 553 | if __name__ == '__main__': 554 | serial_out = sys.stdin.readlines() 555 | 556 | test_name = None 557 | state = 0 558 | data = [] 559 | pat = re.compile(r"========== START (.+) ==========") 560 | for line in serial_out: 561 | if line in ('', '\n'): 562 | continue 563 | if state == 0: 564 | # 寻找测试样例开头 565 | if pat.findall(line): 566 | test_name = pat.findall(line)[0] 567 | # test_name = line.replace("=", '').replace(" ", "").replace("START", "") 568 | if data: 569 | # 只找到了开头没找到结尾,说明某个样例内部使用assert提前退出 570 | r = get_runner(test_name) 571 | if r: 572 | r.start(data) 573 | data = [] 574 | state = 1 575 | elif state == 1: 576 | if "========== END " in line: 577 | # 测试样例结尾 578 | r = get_runner(test_name) 579 | if r: 580 | r.start(data) 581 | state = 0 582 | data = [] 583 | continue 584 | elif pat.findall(line): 585 | data = [] 586 | test_name = pat.findall(line)[0] 587 | # test_name = line.replace("=", '').replace(" ", "").replace("START", "") 588 | continue 589 | # 测试样例中间 590 | data.append(line) 591 | test_results = [x.get_result() for x in runner.values()] 592 | print(json.dumps(test_results)) 593 | -------------------------------------------------------------------------------- /judge/judge_busybox.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | import sys 4 | 5 | cmds = """ 6 | echo "#### independent command test" 7 | ash -c exit 8 | sh -c exit 9 | basename /aaa/bbb 10 | cal 11 | clear 12 | date 13 | df 14 | dirname /aaa/bbb 15 | dmesg 16 | du 17 | expr 1 + 1 18 | false 19 | true 20 | which ls 21 | uname 22 | uptime 23 | ps 24 | pwd 25 | free 26 | hwclock 27 | kill 10 28 | ls 29 | sleep 1 30 | echo "#### file opration test" 31 | touch test.txt 32 | echo "hello world" > test.txt 33 | cat test.txt 34 | cut -c 3 test.txt 35 | od test.txt 36 | head test.txt 37 | tail test.txt 38 | hexdump -C test.txt 39 | md5sum test.txt 40 | echo "ccccccc" >> test.txt 41 | echo "bbbbbbb" >> test.txt 42 | echo "aaaaaaa" >> test.txt 43 | echo "2222222" >> test.txt 44 | echo "1111111" >> test.txt 45 | echo "bbbbbbb" >> test.txt 46 | sort test.txt | ./busybox uniq 47 | stat test.txt 48 | strings test.txt 49 | wc test.txt 50 | [ -f test.txt ] 51 | more test.txt 52 | rm test.txt 53 | mkdir test_dir 54 | mv test_dir test 55 | rmdir test 56 | grep hello busybox_cmd.txt 57 | cp busybox_cmd.txt busybox_cmd.bak 58 | rm busybox_cmd.bak 59 | find -name "busybox_cmd.txt" 60 | """ 61 | 62 | serial_out = sys.stdin.read() 63 | result = {} 64 | pattern = re.compile(r"testcase (.+) (\bsuccess\b|\bfail\b)") 65 | results = pattern.findall(serial_out) 66 | results = {x[0].strip(): x[1] == 'success' for x in results} 67 | 68 | for line in cmds.split('\n'): 69 | line = line.strip() 70 | if not line: 71 | continue 72 | if f"busybox {line}" not in results.keys(): 73 | results[f"busybox {line}"] = False 74 | 75 | results = [{ 76 | "name": k, 77 | "pass": 1 if v else 0, 78 | "all": 1, 79 | "score": 1 if v else 0, 80 | } 81 | for k, v in results.items() 82 | ] 83 | 84 | print(json.dumps(results)) -------------------------------------------------------------------------------- /judge/judge_iozone.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | 4 | iozone_baseline = """ 5 | iozone throughput write/read measurements 6 | Iozone: Performance Test of File I/O 7 | Version $Revision: 3.506 $ 8 | Compiled for 64 bit mode. 9 | Build: linux 10 | 11 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 12 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 13 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 14 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 15 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 16 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 17 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 18 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 19 | Alexey Skidanov, Sudhir Kumar. 20 | 21 | Run began: Mon Jun 12 12:54:02 2023 22 | 23 | Record Size 1 kB 24 | File size set to 1024 kB 25 | Command line used: iozone -t 4 -i 0 -i 1 -r 1k -s 1m 26 | Output is in kBytes/sec 27 | Time Resolution = 0.000007 seconds. 28 | Processor cache size set to 1024 kBytes. 29 | Processor cache line size set to 32 bytes. 30 | File stride size set to 17 * record size. 31 | Throughput test with 4 processes 32 | Each process writes a 1024 kByte file in 1 kByte records 33 | 34 | Children see throughput for 4 initial writers = 13545.93 kB/sec 35 | Parent sees throughput for 4 initial writers = 11624.25 kB/sec 36 | Min throughput per process = 3291.54 kB/sec 37 | Max throughput per process = 3524.04 kB/sec 38 | Avg throughput per process = 3386.48 kB/sec 39 | Min xfer = 960.00 kB 40 | 41 | Children see throughput for 4 rewriters = 28140.14 kB/sec 42 | Parent sees throughput for 4 rewriters = 18228.01 kB/sec 43 | Min throughput per process = 6558.38 kB/sec 44 | Max throughput per process = 7471.07 kB/sec 45 | Avg throughput per process = 7035.03 kB/sec 46 | Min xfer = 938.00 kB 47 | 48 | Children see throughput for 4 readers = 50931.58 kB/sec 49 | Parent sees throughput for 4 readers = 41114.90 kB/sec 50 | Min throughput per process = 12200.35 kB/sec 51 | Max throughput per process = 13135.64 kB/sec 52 | Avg throughput per process = 12732.90 kB/sec 53 | Min xfer = 940.00 kB 54 | 55 | Children see throughput for 4 re-readers = 48204.08 kB/sec 56 | Parent sees throughput for 4 re-readers = 34139.58 kB/sec 57 | Min throughput per process = 10801.74 kB/sec 58 | Max throughput per process = 13064.75 kB/sec 59 | Avg throughput per process = 12051.02 kB/sec 60 | Min xfer = 883.00 kB 61 | 62 | 63 | 64 | iozone test complete. 65 | iozone throughput random-read measurements 66 | Iozone: Performance Test of File I/O 67 | Version $Revision: 3.506 $ 68 | Compiled for 64 bit mode. 69 | Build: linux 70 | 71 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 72 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 73 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 74 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 75 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 76 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 77 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 78 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 79 | Alexey Skidanov, Sudhir Kumar. 80 | 81 | Run began: Mon Jun 12 12:54:15 2023 82 | 83 | Record Size 1 kB 84 | File size set to 1024 kB 85 | Command line used: iozone -t 4 -i 0 -i 2 -r 1k -s 1m 86 | Output is in kBytes/sec 87 | Time Resolution = 0.000007 seconds. 88 | Processor cache size set to 1024 kBytes. 89 | Processor cache line size set to 32 bytes. 90 | File stride size set to 17 * record size. 91 | Throughput test with 4 processes 92 | Each process writes a 1024 kByte file in 1 kByte records 93 | 94 | Children see throughput for 4 initial writers = 13180.57 kB/sec 95 | Parent sees throughput for 4 initial writers = 10159.23 kB/sec 96 | Min throughput per process = 3182.96 kB/sec 97 | Max throughput per process = 3401.72 kB/sec 98 | Avg throughput per process = 3295.14 kB/sec 99 | Min xfer = 974.00 kB 100 | 101 | Children see throughput for 4 rewriters = 27019.84 kB/sec 102 | Parent sees throughput for 4 rewriters = 18318.53 kB/sec 103 | Min throughput per process = 6345.39 kB/sec 104 | Max throughput per process = 7196.32 kB/sec 105 | Avg throughput per process = 6754.96 kB/sec 106 | Min xfer = 943.00 kB 107 | 108 | Children see throughput for 4 random readers = 41679.51 kB/sec 109 | Parent sees throughput for 4 random readers = 32154.24 kB/sec 110 | Min throughput per process = 9572.77 kB/sec 111 | Max throughput per process = 11082.03 kB/sec 112 | Avg throughput per process = 10419.88 kB/sec 113 | Min xfer = 920.00 kB 114 | 115 | Children see throughput for 4 random writers = 25554.45 kB/sec 116 | Parent sees throughput for 4 random writers = 15585.05 kB/sec 117 | Min throughput per process = 5886.12 kB/sec 118 | Max throughput per process = 7140.81 kB/sec 119 | Avg throughput per process = 6388.61 kB/sec 120 | Min xfer = 847.00 kB 121 | 122 | 123 | 124 | iozone test complete. 125 | iozone throughput read-backwards measurements 126 | Iozone: Performance Test of File I/O 127 | Version $Revision: 3.506 $ 128 | Compiled for 64 bit mode. 129 | Build: linux 130 | 131 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 132 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 133 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 134 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 135 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 136 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 137 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 138 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 139 | Alexey Skidanov, Sudhir Kumar. 140 | 141 | Run began: Mon Jun 12 12:54:32 2023 142 | 143 | Record Size 1 kB 144 | File size set to 1024 kB 145 | Command line used: iozone -t 4 -i 0 -i 3 -r 1k -s 1m 146 | Output is in kBytes/sec 147 | Time Resolution = 0.000007 seconds. 148 | Processor cache size set to 1024 kBytes. 149 | Processor cache line size set to 32 bytes. 150 | File stride size set to 17 * record size. 151 | Throughput test with 4 processes 152 | Each process writes a 1024 kByte file in 1 kByte records 153 | 154 | Children see throughput for 4 initial writers = 12570.89 kB/sec 155 | Parent sees throughput for 4 initial writers = 9732.30 kB/sec 156 | Min throughput per process = 2968.10 kB/sec 157 | Max throughput per process = 3331.39 kB/sec 158 | Avg throughput per process = 3142.72 kB/sec 159 | Min xfer = 952.00 kB 160 | 161 | Children see throughput for 4 rewriters = 19325.11 kB/sec 162 | Parent sees throughput for 4 rewriters = 14720.52 kB/sec 163 | Min throughput per process = 4782.28 kB/sec 164 | Max throughput per process = 4906.05 kB/sec 165 | Avg throughput per process = 4831.28 kB/sec 166 | Min xfer = 981.00 kB 167 | 168 | Children see throughput for 4 reverse readers = 39143.26 kB/sec 169 | Parent sees throughput for 4 reverse readers = 29813.36 kB/sec 170 | Min throughput per process = 8622.26 kB/sec 171 | Max throughput per process = 10743.42 kB/sec 172 | Avg throughput per process = 9785.82 kB/sec 173 | Min xfer = 862.00 kB 174 | 175 | 176 | 177 | iozone test complete. 178 | iozone throughput stride-read measurements 179 | Iozone: Performance Test of File I/O 180 | Version $Revision: 3.506 $ 181 | Compiled for 64 bit mode. 182 | Build: linux 183 | 184 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 185 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 186 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 187 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 188 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 189 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 190 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 191 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 192 | Alexey Skidanov, Sudhir Kumar. 193 | 194 | Run began: Mon Jun 12 12:54:45 2023 195 | 196 | Record Size 1 kB 197 | File size set to 1024 kB 198 | Command line used: iozone -t 4 -i 0 -i 5 -r 1k -s 1m 199 | Output is in kBytes/sec 200 | Time Resolution = 0.000008 seconds. 201 | Processor cache size set to 1024 kBytes. 202 | Processor cache line size set to 32 bytes. 203 | File stride size set to 17 * record size. 204 | Throughput test with 4 processes 205 | Each process writes a 1024 kByte file in 1 kByte records 206 | 207 | Children see throughput for 4 initial writers = 13264.41 kB/sec 208 | Parent sees throughput for 4 initial writers = 10461.44 kB/sec 209 | Min throughput per process = 3175.73 kB/sec 210 | Max throughput per process = 3468.09 kB/sec 211 | Avg throughput per process = 3316.10 kB/sec 212 | Min xfer = 940.00 kB 213 | 214 | Children see throughput for 4 rewriters = 26812.58 kB/sec 215 | Parent sees throughput for 4 rewriters = 19308.66 kB/sec 216 | Min throughput per process = 6404.84 kB/sec 217 | Max throughput per process = 7004.64 kB/sec 218 | Avg throughput per process = 6703.14 kB/sec 219 | Min xfer = 987.00 kB 220 | 221 | Children see throughput for 4 stride readers = 42873.56 kB/sec 222 | Parent sees throughput for 4 stride readers = 36079.78 kB/sec 223 | Min throughput per process = 9306.99 kB/sec 224 | Max throughput per process = 11848.11 kB/sec 225 | Avg throughput per process = 10718.39 kB/sec 226 | Min xfer = 874.00 kB 227 | 228 | 229 | 230 | iozone test complete. 231 | iozone throughput fwrite/fread measurements 232 | Iozone: Performance Test of File I/O 233 | Version $Revision: 3.506 $ 234 | Compiled for 64 bit mode. 235 | Build: linux 236 | 237 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 238 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 239 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 240 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 241 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 242 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 243 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 244 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 245 | Alexey Skidanov, Sudhir Kumar. 246 | 247 | Run began: Mon Jun 12 12:54:58 2023 248 | 249 | Record Size 1 kB 250 | File size set to 1024 kB 251 | Command line used: iozone -t 4 -i 6 -i 7 -r 1k -s 1m 252 | Output is in kBytes/sec 253 | Time Resolution = 0.000007 seconds. 254 | Processor cache size set to 1024 kBytes. 255 | Processor cache line size set to 32 bytes. 256 | File stride size set to 17 * record size. 257 | Throughput test with 4 processes 258 | Each process writes a 1024 kByte file in 1 kByte records 259 | 260 | Children see throughput for 4 fwriters = 12272.83 kB/sec 261 | Parent sees throughput for 4 fwriters = 9606.97 kB/sec 262 | Min throughput per process = 2886.12 kB/sec 263 | Max throughput per process = 3204.25 kB/sec 264 | Avg throughput per process = 3068.21 kB/sec 265 | Min xfer = 1024.00 kB 266 | 267 | Children see throughput for 4 freaders = 26930.34 kB/sec 268 | Parent sees throughput for 4 freaders = 24595.56 kB/sec 269 | Min throughput per process = 6392.92 kB/sec 270 | Max throughput per process = 7123.18 kB/sec 271 | Avg throughput per process = 6732.58 kB/sec 272 | Min xfer = 1024.00 kB 273 | 274 | 275 | 276 | iozone test complete. 277 | iozone throughput pwrite/pread measurements 278 | Iozone: Performance Test of File I/O 279 | Version $Revision: 3.506 $ 280 | Compiled for 64 bit mode. 281 | Build: linux 282 | 283 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 284 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 285 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 286 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 287 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 288 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 289 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 290 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 291 | Alexey Skidanov, Sudhir Kumar. 292 | 293 | Run began: Mon Jun 12 12:55:07 2023 294 | 295 | Record Size 1 kB 296 | File size set to 1024 kB 297 | Command line used: iozone -t 4 -i 9 -i 10 -r 1k -s 1m 298 | Output is in kBytes/sec 299 | Time Resolution = 0.000007 seconds. 300 | Processor cache size set to 1024 kBytes. 301 | Processor cache line size set to 32 bytes. 302 | File stride size set to 17 * record size. 303 | Throughput test with 4 processes 304 | Each process writes a 1024 kByte file in 1 kByte records 305 | 306 | Children see throughput for 4 pwrite writers = 14005.01 kB/sec 307 | Parent sees throughput for 4 pwrite writers = 11383.99 kB/sec 308 | Min throughput per process = 3371.57 kB/sec 309 | Max throughput per process = 3724.00 kB/sec 310 | Avg throughput per process = 3501.25 kB/sec 311 | Min xfer = 967.00 kB 312 | 313 | Children see throughput for 4 pread readers = 53217.58 kB/sec 314 | Parent sees throughput for 4 pread readers = 38787.67 kB/sec 315 | Min throughput per process = 12224.63 kB/sec 316 | Max throughput per process = 14183.61 kB/sec 317 | Avg throughput per process = 13304.40 kB/sec 318 | Min xfer = 980.00 kB 319 | 320 | 321 | 322 | iozone test complete. 323 | iozone throughtput pwritev/preadv measurements 324 | Iozone: Performance Test of File I/O 325 | Version $Revision: 3.506 $ 326 | Compiled for 64 bit mode. 327 | Build: linux 328 | 329 | Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins 330 | Al Slater, Scott Rhine, Mike Wisner, Ken Goss 331 | Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR, 332 | Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner, 333 | Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone, 334 | Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root, 335 | Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer, 336 | Vangel Bojaxhi, Ben England, Vikentsi Lapa, 337 | Alexey Skidanov, Sudhir Kumar. 338 | 339 | Run began: Mon Jun 12 12:55:20 2023 340 | 341 | Selected test not available on the version. 342 | Record Size 1 kB 343 | File size set to 1024 kB 344 | Command line used: iozone -t 4 -i 11 -i 12 -r 1k -s 1m 345 | Output is in kBytes/sec 346 | Time Resolution = 0.000007 seconds. 347 | Processor cache size set to 1024 kBytes. 348 | Processor cache line size set to 32 bytes. 349 | File stride size set to 17 * record size. 350 | Throughput test with 4 processes 351 | Each process writes a 1024 kByte file in 1 kByte records 352 | 353 | Children see throughput for 4 initial writers = 14056.85 kB/sec 354 | Parent sees throughput for 4 initial writers = 11748.06 kB/sec 355 | Min throughput per process = 3440.28 kB/sec 356 | Max throughput per process = 3609.25 kB/sec 357 | Avg throughput per process = 3514.21 kB/sec 358 | Min xfer = 967.00 kB 359 | 360 | Children see throughput for 4 rewriters = 30184.44 kB/sec 361 | Parent sees throughput for 4 rewriters = 21066.51 kB/sec 362 | Min throughput per process = 6812.83 kB/sec 363 | Max throughput per process = 8305.90 kB/sec 364 | Avg throughput per process = 7546.11 kB/sec 365 | Min xfer = 903.00 kB 366 | 367 | 368 | 369 | iozone test complete. 370 | """ 371 | 372 | def parse_iozone(output: str): 373 | ans = {} 374 | lines = output.split("\n") 375 | current_key = "" 376 | sub_key = "" 377 | for line in lines: 378 | if "iozone throughput write/read measurements" in line: 379 | current_key = "iozone write/read" 380 | elif "iozone throughput random-read measurements" in line: 381 | current_key = "iozone random-read" 382 | elif "iozone throughput read-backwards measurements" in line: 383 | current_key = "iozone read-backwards" 384 | elif "iozone throughput stride-read measurements" in line: 385 | current_key = "iozone stride-read" 386 | elif "iozone throughput fwrite/fread measurements" in line: 387 | current_key = "iozone fwrite/fread" 388 | elif "iozone throughput pwrite/pread measurements" in line: 389 | current_key = "iozone pwrite/pread" 390 | elif "iozone throughtput pwritev/preadv measurements" in line: 391 | current_key = "iozone pwritev/preadv" 392 | 393 | if "Children see throughput for" in line: 394 | sub_key = line.replace("Children see throughput for", "").strip() 395 | sub_key = sub_key.split("=")[0] 396 | sub_key = sub_key.strip() 397 | 398 | if "Max throughput per process" in line: 399 | key = f"{current_key} {sub_key} (kb/sec)" 400 | ans[key] = float(line.split("=")[1].split()[0]) 401 | 402 | return ans 403 | 404 | serial_out = sys.stdin.read() 405 | results = parse_iozone(serial_out) 406 | baseline = parse_iozone(iozone_baseline) 407 | lmbench_results = results 408 | lmbench_baseline = baseline 409 | lmbench = [ 410 | { 411 | "name": name, 412 | "result": lmbench_results.get(name, 0), 413 | "baseline": baseline, 414 | "score": 0.0 415 | } 416 | for name, baseline in lmbench_baseline.items() 417 | ] 418 | for item in lmbench: 419 | if item["result"] > 0: 420 | if "microseconds" in item["name"] or "seconds" in item["name"]: 421 | item["score"] = item["baseline"] / item["res"] 422 | else: 423 | item["score"] = item["result"] / item["baseline"] 424 | 425 | if item['score'] >= 1: 426 | item['score'] = 2 - (1 / item['score']) 427 | else: 428 | item['score'] = 1.0 429 | print(json.dumps(lmbench)) -------------------------------------------------------------------------------- /judge/judge_libctest.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | 4 | libctest_baseline = """ 5 | ========== START entry-static.exe argv ========== 6 | Pass! 7 | ========== END entry-static.exe argv ========== 8 | ========== START entry-static.exe basename ========== 9 | Pass! 10 | ========== END entry-static.exe basename ========== 11 | ========== START entry-static.exe clocale_mbfuncs ========== 12 | Pass! 13 | ========== END entry-static.exe clocale_mbfuncs ========== 14 | ========== START entry-static.exe clock_gettime ========== 15 | Pass! 16 | ========== END entry-static.exe clock_gettime ========== 17 | ========== START entry-static.exe crypt ========== 18 | Pass! 19 | ========== END entry-static.exe crypt ========== 20 | ========== START entry-static.exe dirname ========== 21 | Pass! 22 | ========== END entry-static.exe dirname ========== 23 | ========== START entry-static.exe env ========== 24 | Pass! 25 | ========== END entry-static.exe env ========== 26 | ========== START entry-static.exe fdopen ========== 27 | Pass! 28 | ========== END entry-static.exe fdopen ========== 29 | ========== START entry-static.exe fnmatch ========== 30 | Pass! 31 | ========== END entry-static.exe fnmatch ========== 32 | ========== START entry-static.exe fscanf ========== 33 | Pass! 34 | ========== END entry-static.exe fscanf ========== 35 | ========== START entry-static.exe fwscanf ========== 36 | Pass! 37 | ========== END entry-static.exe fwscanf ========== 38 | ========== START entry-static.exe iconv_open ========== 39 | Pass! 40 | ========== END entry-static.exe iconv_open ========== 41 | ========== START entry-static.exe inet_pton ========== 42 | Pass! 43 | ========== END entry-static.exe inet_pton ========== 44 | ========== START entry-static.exe mbc ========== 45 | Pass! 46 | ========== END entry-static.exe mbc ========== 47 | ========== START entry-static.exe memstream ========== 48 | Pass! 49 | ========== END entry-static.exe memstream ========== 50 | ========== START entry-static.exe pthread_cancel_points ========== 51 | Pass! 52 | ========== END entry-static.exe pthread_cancel_points ========== 53 | ========== START entry-static.exe pthread_cancel ========== 54 | Pass! 55 | ========== END entry-static.exe pthread_cancel ========== 56 | ========== START entry-static.exe pthread_cond ========== 57 | Pass! 58 | ========== END entry-static.exe pthread_cond ========== 59 | ========== START entry-static.exe pthread_tsd ========== 60 | Pass! 61 | ========== END entry-static.exe pthread_tsd ========== 62 | ========== START entry-static.exe qsort ========== 63 | Pass! 64 | ========== END entry-static.exe qsort ========== 65 | ========== START entry-static.exe random ========== 66 | Pass! 67 | ========== END entry-static.exe random ========== 68 | ========== START entry-static.exe search_hsearch ========== 69 | Pass! 70 | ========== END entry-static.exe search_hsearch ========== 71 | ========== START entry-static.exe search_insque ========== 72 | Pass! 73 | ========== END entry-static.exe search_insque ========== 74 | ========== START entry-static.exe search_lsearch ========== 75 | Pass! 76 | ========== END entry-static.exe search_lsearch ========== 77 | ========== START entry-static.exe search_tsearch ========== 78 | Pass! 79 | ========== END entry-static.exe search_tsearch ========== 80 | ========== START entry-static.exe setjmp ========== 81 | Pass! 82 | ========== END entry-static.exe setjmp ========== 83 | ========== START entry-static.exe snprintf ========== 84 | Pass! 85 | ========== END entry-static.exe snprintf ========== 86 | ========== START entry-static.exe socket ========== 87 | Pass! 88 | ========== END entry-static.exe socket ========== 89 | ========== START entry-static.exe sscanf ========== 90 | Pass! 91 | ========== END entry-static.exe sscanf ========== 92 | ========== START entry-static.exe sscanf_long ========== 93 | Pass! 94 | ========== END entry-static.exe sscanf_long ========== 95 | ========== START entry-static.exe stat ========== 96 | Pass! 97 | ========== END entry-static.exe stat ========== 98 | ========== START entry-static.exe strftime ========== 99 | Pass! 100 | ========== END entry-static.exe strftime ========== 101 | ========== START entry-static.exe string ========== 102 | Pass! 103 | ========== END entry-static.exe string ========== 104 | ========== START entry-static.exe string_memcpy ========== 105 | Pass! 106 | ========== END entry-static.exe string_memcpy ========== 107 | ========== START entry-static.exe string_memmem ========== 108 | Pass! 109 | ========== END entry-static.exe string_memmem ========== 110 | ========== START entry-static.exe string_memset ========== 111 | Pass! 112 | ========== END entry-static.exe string_memset ========== 113 | ========== START entry-static.exe string_strchr ========== 114 | Pass! 115 | ========== END entry-static.exe string_strchr ========== 116 | ========== START entry-static.exe string_strcspn ========== 117 | Pass! 118 | ========== END entry-static.exe string_strcspn ========== 119 | ========== START entry-static.exe string_strstr ========== 120 | Pass! 121 | ========== END entry-static.exe string_strstr ========== 122 | ========== START entry-static.exe strptime ========== 123 | Pass! 124 | ========== END entry-static.exe strptime ========== 125 | ========== START entry-static.exe strtod ========== 126 | Pass! 127 | ========== END entry-static.exe strtod ========== 128 | ========== START entry-static.exe strtod_simple ========== 129 | Pass! 130 | ========== END entry-static.exe strtod_simple ========== 131 | ========== START entry-static.exe strtof ========== 132 | Pass! 133 | ========== END entry-static.exe strtof ========== 134 | ========== START entry-static.exe strtol ========== 135 | Pass! 136 | ========== END entry-static.exe strtol ========== 137 | ========== START entry-static.exe strtold ========== 138 | Pass! 139 | ========== END entry-static.exe strtold ========== 140 | ========== START entry-static.exe swprintf ========== 141 | Pass! 142 | ========== END entry-static.exe swprintf ========== 143 | ========== START entry-static.exe tgmath ========== 144 | Pass! 145 | ========== END entry-static.exe tgmath ========== 146 | ========== START entry-static.exe time ========== 147 | Pass! 148 | ========== END entry-static.exe time ========== 149 | ========== START entry-static.exe tls_align ========== 150 | Pass! 151 | ========== END entry-static.exe tls_align ========== 152 | ========== START entry-static.exe udiv ========== 153 | Pass! 154 | ========== END entry-static.exe udiv ========== 155 | ========== START entry-static.exe ungetc ========== 156 | Pass! 157 | ========== END entry-static.exe ungetc ========== 158 | ========== START entry-static.exe utime ========== 159 | Pass! 160 | ========== END entry-static.exe utime ========== 161 | ========== START entry-static.exe wcsstr ========== 162 | Pass! 163 | ========== END entry-static.exe wcsstr ========== 164 | ========== START entry-static.exe wcstol ========== 165 | Pass! 166 | ========== END entry-static.exe wcstol ========== 167 | ========== START entry-static.exe pleval ========== 168 | Pass! 169 | ========== END entry-static.exe pleval ========== 170 | ========== START entry-static.exe daemon_failure ========== 171 | Pass! 172 | ========== END entry-static.exe daemon_failure ========== 173 | ========== START entry-static.exe dn_expand_empty ========== 174 | Pass! 175 | ========== END entry-static.exe dn_expand_empty ========== 176 | ========== START entry-static.exe dn_expand_ptr_0 ========== 177 | Pass! 178 | ========== END entry-static.exe dn_expand_ptr_0 ========== 179 | ========== START entry-static.exe fflush_exit ========== 180 | Pass! 181 | ========== END entry-static.exe fflush_exit ========== 182 | ========== START entry-static.exe fgets_eof ========== 183 | Pass! 184 | ========== END entry-static.exe fgets_eof ========== 185 | ========== START entry-static.exe fgetwc_buffering ========== 186 | Pass! 187 | ========== END entry-static.exe fgetwc_buffering ========== 188 | ========== START entry-static.exe fpclassify_invalid_ld80 ========== 189 | Pass! 190 | ========== END entry-static.exe fpclassify_invalid_ld80 ========== 191 | ========== START entry-static.exe ftello_unflushed_append ========== 192 | Pass! 193 | ========== END entry-static.exe ftello_unflushed_append ========== 194 | ========== START entry-static.exe getpwnam_r_crash ========== 195 | Pass! 196 | ========== END entry-static.exe getpwnam_r_crash ========== 197 | ========== START entry-static.exe getpwnam_r_errno ========== 198 | Pass! 199 | ========== END entry-static.exe getpwnam_r_errno ========== 200 | ========== START entry-static.exe iconv_roundtrips ========== 201 | Pass! 202 | ========== END entry-static.exe iconv_roundtrips ========== 203 | ========== START entry-static.exe inet_ntop_v4mapped ========== 204 | Pass! 205 | ========== END entry-static.exe inet_ntop_v4mapped ========== 206 | ========== START entry-static.exe inet_pton_empty_last_field ========== 207 | Pass! 208 | ========== END entry-static.exe inet_pton_empty_last_field ========== 209 | ========== START entry-static.exe iswspace_null ========== 210 | Pass! 211 | ========== END entry-static.exe iswspace_null ========== 212 | ========== START entry-static.exe lrand48_signextend ========== 213 | Pass! 214 | ========== END entry-static.exe lrand48_signextend ========== 215 | ========== START entry-static.exe lseek_large ========== 216 | Pass! 217 | ========== END entry-static.exe lseek_large ========== 218 | ========== START entry-static.exe malloc_0 ========== 219 | Pass! 220 | ========== END entry-static.exe malloc_0 ========== 221 | ========== START entry-static.exe mbsrtowcs_overflow ========== 222 | Pass! 223 | ========== END entry-static.exe mbsrtowcs_overflow ========== 224 | ========== START entry-static.exe memmem_oob_read ========== 225 | Pass! 226 | ========== END entry-static.exe memmem_oob_read ========== 227 | ========== START entry-static.exe memmem_oob ========== 228 | Pass! 229 | ========== END entry-static.exe memmem_oob ========== 230 | ========== START entry-static.exe mkdtemp_failure ========== 231 | Pass! 232 | ========== END entry-static.exe mkdtemp_failure ========== 233 | ========== START entry-static.exe mkstemp_failure ========== 234 | Pass! 235 | ========== END entry-static.exe mkstemp_failure ========== 236 | ========== START entry-static.exe printf_1e9_oob ========== 237 | Pass! 238 | ========== END entry-static.exe printf_1e9_oob ========== 239 | ========== START entry-static.exe printf_fmt_g_round ========== 240 | Pass! 241 | ========== END entry-static.exe printf_fmt_g_round ========== 242 | ========== START entry-static.exe printf_fmt_g_zeros ========== 243 | Pass! 244 | ========== END entry-static.exe printf_fmt_g_zeros ========== 245 | ========== START entry-static.exe printf_fmt_n ========== 246 | Pass! 247 | ========== END entry-static.exe printf_fmt_n ========== 248 | ========== START entry-static.exe pthread_robust_detach ========== 249 | Pass! 250 | ========== END entry-static.exe pthread_robust_detach ========== 251 | ========== START entry-static.exe pthread_cancel_sem_wait ========== 252 | Pass! 253 | ========== END entry-static.exe pthread_cancel_sem_wait ========== 254 | ========== START entry-static.exe pthread_cond_smasher ========== 255 | Pass! 256 | ========== END entry-static.exe pthread_cond_smasher ========== 257 | ========== START entry-static.exe pthread_condattr_setclock ========== 258 | Pass! 259 | ========== END entry-static.exe pthread_condattr_setclock ========== 260 | ========== START entry-static.exe pthread_exit_cancel ========== 261 | Pass! 262 | ========== END entry-static.exe pthread_exit_cancel ========== 263 | ========== START entry-static.exe pthread_once_deadlock ========== 264 | Pass! 265 | ========== END entry-static.exe pthread_once_deadlock ========== 266 | ========== START entry-static.exe pthread_rwlock_ebusy ========== 267 | Pass! 268 | ========== END entry-static.exe pthread_rwlock_ebusy ========== 269 | ========== START entry-static.exe putenv_doublefree ========== 270 | Pass! 271 | ========== END entry-static.exe putenv_doublefree ========== 272 | ========== START entry-static.exe regex_backref_0 ========== 273 | Pass! 274 | ========== END entry-static.exe regex_backref_0 ========== 275 | ========== START entry-static.exe regex_bracket_icase ========== 276 | Pass! 277 | ========== END entry-static.exe regex_bracket_icase ========== 278 | ========== START entry-static.exe regex_ere_backref ========== 279 | Pass! 280 | ========== END entry-static.exe regex_ere_backref ========== 281 | ========== START entry-static.exe regex_escaped_high_byte ========== 282 | Pass! 283 | ========== END entry-static.exe regex_escaped_high_byte ========== 284 | ========== START entry-static.exe regex_negated_range ========== 285 | Pass! 286 | ========== END entry-static.exe regex_negated_range ========== 287 | ========== START entry-static.exe regexec_nosub ========== 288 | Pass! 289 | ========== END entry-static.exe regexec_nosub ========== 290 | ========== START entry-static.exe rewind_clear_error ========== 291 | Pass! 292 | ========== END entry-static.exe rewind_clear_error ========== 293 | ========== START entry-static.exe rlimit_open_files ========== 294 | Pass! 295 | ========== END entry-static.exe rlimit_open_files ========== 296 | ========== START entry-static.exe scanf_bytes_consumed ========== 297 | Pass! 298 | ========== END entry-static.exe scanf_bytes_consumed ========== 299 | ========== START entry-static.exe scanf_match_literal_eof ========== 300 | Pass! 301 | ========== END entry-static.exe scanf_match_literal_eof ========== 302 | ========== START entry-static.exe scanf_nullbyte_char ========== 303 | Pass! 304 | ========== END entry-static.exe scanf_nullbyte_char ========== 305 | ========== START entry-static.exe setvbuf_unget ========== 306 | Pass! 307 | ========== END entry-static.exe setvbuf_unget ========== 308 | ========== START entry-static.exe sigprocmask_internal ========== 309 | Pass! 310 | ========== END entry-static.exe sigprocmask_internal ========== 311 | ========== START entry-static.exe sscanf_eof ========== 312 | Pass! 313 | ========== END entry-static.exe sscanf_eof ========== 314 | ========== START entry-static.exe statvfs ========== 315 | Pass! 316 | ========== END entry-static.exe statvfs ========== 317 | ========== START entry-static.exe strverscmp ========== 318 | Pass! 319 | ========== END entry-static.exe strverscmp ========== 320 | ========== START entry-static.exe syscall_sign_extend ========== 321 | Pass! 322 | ========== END entry-static.exe syscall_sign_extend ========== 323 | ========== START entry-static.exe uselocale_0 ========== 324 | Pass! 325 | ========== END entry-static.exe uselocale_0 ========== 326 | ========== START entry-static.exe wcsncpy_read_overflow ========== 327 | Pass! 328 | ========== END entry-static.exe wcsncpy_read_overflow ========== 329 | ========== START entry-static.exe wcsstr_false_negative ========== 330 | Pass! 331 | ========== END entry-static.exe wcsstr_false_negative ========== 332 | ========== START entry-dynamic.exe argv ========== 333 | Pass! 334 | ========== END entry-dynamic.exe argv ========== 335 | ========== START entry-dynamic.exe basename ========== 336 | Pass! 337 | ========== END entry-dynamic.exe basename ========== 338 | ========== START entry-dynamic.exe clocale_mbfuncs ========== 339 | Pass! 340 | ========== END entry-dynamic.exe clocale_mbfuncs ========== 341 | ========== START entry-dynamic.exe clock_gettime ========== 342 | Pass! 343 | ========== END entry-dynamic.exe clock_gettime ========== 344 | ========== START entry-dynamic.exe crypt ========== 345 | Pass! 346 | ========== END entry-dynamic.exe crypt ========== 347 | ========== START entry-dynamic.exe dirname ========== 348 | Pass! 349 | ========== END entry-dynamic.exe dirname ========== 350 | ========== START entry-dynamic.exe dlopen ========== 351 | Pass! 352 | ========== END entry-dynamic.exe dlopen ========== 353 | ========== START entry-dynamic.exe env ========== 354 | Pass! 355 | ========== END entry-dynamic.exe env ========== 356 | ========== START entry-dynamic.exe fdopen ========== 357 | Pass! 358 | ========== END entry-dynamic.exe fdopen ========== 359 | ========== START entry-dynamic.exe fnmatch ========== 360 | Pass! 361 | ========== END entry-dynamic.exe fnmatch ========== 362 | ========== START entry-dynamic.exe fscanf ========== 363 | Pass! 364 | ========== END entry-dynamic.exe fscanf ========== 365 | ========== START entry-dynamic.exe fwscanf ========== 366 | Pass! 367 | ========== END entry-dynamic.exe fwscanf ========== 368 | ========== START entry-dynamic.exe iconv_open ========== 369 | Pass! 370 | ========== END entry-dynamic.exe iconv_open ========== 371 | ========== START entry-dynamic.exe inet_pton ========== 372 | Pass! 373 | ========== END entry-dynamic.exe inet_pton ========== 374 | ========== START entry-dynamic.exe mbc ========== 375 | Pass! 376 | ========== END entry-dynamic.exe mbc ========== 377 | ========== START entry-dynamic.exe memstream ========== 378 | Pass! 379 | ========== END entry-dynamic.exe memstream ========== 380 | ========== START entry-dynamic.exe pthread_cancel_points ========== 381 | Pass! 382 | ========== END entry-dynamic.exe pthread_cancel_points ========== 383 | ========== START entry-dynamic.exe pthread_cancel ========== 384 | Pass! 385 | ========== END entry-dynamic.exe pthread_cancel ========== 386 | ========== START entry-dynamic.exe pthread_cond ========== 387 | Pass! 388 | ========== END entry-dynamic.exe pthread_cond ========== 389 | ========== START entry-dynamic.exe pthread_tsd ========== 390 | Pass! 391 | ========== END entry-dynamic.exe pthread_tsd ========== 392 | ========== START entry-dynamic.exe qsort ========== 393 | Pass! 394 | ========== END entry-dynamic.exe qsort ========== 395 | ========== START entry-dynamic.exe random ========== 396 | Pass! 397 | ========== END entry-dynamic.exe random ========== 398 | ========== START entry-dynamic.exe search_hsearch ========== 399 | Pass! 400 | ========== END entry-dynamic.exe search_hsearch ========== 401 | ========== START entry-dynamic.exe search_insque ========== 402 | Pass! 403 | ========== END entry-dynamic.exe search_insque ========== 404 | ========== START entry-dynamic.exe search_lsearch ========== 405 | Pass! 406 | ========== END entry-dynamic.exe search_lsearch ========== 407 | ========== START entry-dynamic.exe search_tsearch ========== 408 | Pass! 409 | ========== END entry-dynamic.exe search_tsearch ========== 410 | ========== START entry-dynamic.exe sem_init ========== 411 | Pass! 412 | ========== END entry-dynamic.exe sem_init ========== 413 | ========== START entry-dynamic.exe setjmp ========== 414 | Pass! 415 | ========== END entry-dynamic.exe setjmp ========== 416 | ========== START entry-dynamic.exe snprintf ========== 417 | Pass! 418 | ========== END entry-dynamic.exe snprintf ========== 419 | ========== START entry-dynamic.exe socket ========== 420 | Pass! 421 | ========== END entry-dynamic.exe socket ========== 422 | ========== START entry-dynamic.exe sscanf ========== 423 | Pass! 424 | ========== END entry-dynamic.exe sscanf ========== 425 | ========== START entry-dynamic.exe sscanf_long ========== 426 | Pass! 427 | ========== END entry-dynamic.exe sscanf_long ========== 428 | ========== START entry-dynamic.exe stat ========== 429 | Pass! 430 | ========== END entry-dynamic.exe stat ========== 431 | ========== START entry-dynamic.exe strftime ========== 432 | Pass! 433 | ========== END entry-dynamic.exe strftime ========== 434 | ========== START entry-dynamic.exe string ========== 435 | Pass! 436 | ========== END entry-dynamic.exe string ========== 437 | ========== START entry-dynamic.exe string_memcpy ========== 438 | Pass! 439 | ========== END entry-dynamic.exe string_memcpy ========== 440 | ========== START entry-dynamic.exe string_memmem ========== 441 | Pass! 442 | ========== END entry-dynamic.exe string_memmem ========== 443 | ========== START entry-dynamic.exe string_memset ========== 444 | Pass! 445 | ========== END entry-dynamic.exe string_memset ========== 446 | ========== START entry-dynamic.exe string_strchr ========== 447 | Pass! 448 | ========== END entry-dynamic.exe string_strchr ========== 449 | ========== START entry-dynamic.exe string_strcspn ========== 450 | Pass! 451 | ========== END entry-dynamic.exe string_strcspn ========== 452 | ========== START entry-dynamic.exe string_strstr ========== 453 | Pass! 454 | ========== END entry-dynamic.exe string_strstr ========== 455 | ========== START entry-dynamic.exe strptime ========== 456 | Pass! 457 | ========== END entry-dynamic.exe strptime ========== 458 | ========== START entry-dynamic.exe strtod ========== 459 | Pass! 460 | ========== END entry-dynamic.exe strtod ========== 461 | ========== START entry-dynamic.exe strtod_simple ========== 462 | Pass! 463 | ========== END entry-dynamic.exe strtod_simple ========== 464 | ========== START entry-dynamic.exe strtof ========== 465 | Pass! 466 | ========== END entry-dynamic.exe strtof ========== 467 | ========== START entry-dynamic.exe strtol ========== 468 | Pass! 469 | ========== END entry-dynamic.exe strtol ========== 470 | ========== START entry-dynamic.exe strtold ========== 471 | Pass! 472 | ========== END entry-dynamic.exe strtold ========== 473 | ========== START entry-dynamic.exe swprintf ========== 474 | Pass! 475 | ========== END entry-dynamic.exe swprintf ========== 476 | ========== START entry-dynamic.exe tgmath ========== 477 | Pass! 478 | ========== END entry-dynamic.exe tgmath ========== 479 | ========== START entry-dynamic.exe time ========== 480 | Pass! 481 | ========== END entry-dynamic.exe time ========== 482 | ========== START entry-dynamic.exe tls_init ========== 483 | Pass! 484 | ========== END entry-dynamic.exe tls_init ========== 485 | ========== START entry-dynamic.exe tls_local_exec ========== 486 | Pass! 487 | ========== END entry-dynamic.exe tls_local_exec ========== 488 | ========== START entry-dynamic.exe udiv ========== 489 | Pass! 490 | ========== END entry-dynamic.exe udiv ========== 491 | ========== START entry-dynamic.exe ungetc ========== 492 | Pass! 493 | ========== END entry-dynamic.exe ungetc ========== 494 | ========== START entry-dynamic.exe utime ========== 495 | Pass! 496 | ========== END entry-dynamic.exe utime ========== 497 | ========== START entry-dynamic.exe wcsstr ========== 498 | Pass! 499 | ========== END entry-dynamic.exe wcsstr ========== 500 | ========== START entry-dynamic.exe wcstol ========== 501 | Pass! 502 | ========== END entry-dynamic.exe wcstol ========== 503 | ========== START entry-dynamic.exe daemon_failure ========== 504 | Pass! 505 | ========== END entry-dynamic.exe daemon_failure ========== 506 | ========== START entry-dynamic.exe dn_expand_empty ========== 507 | Pass! 508 | ========== END entry-dynamic.exe dn_expand_empty ========== 509 | ========== START entry-dynamic.exe dn_expand_ptr_0 ========== 510 | Pass! 511 | ========== END entry-dynamic.exe dn_expand_ptr_0 ========== 512 | ========== START entry-dynamic.exe fflush_exit ========== 513 | Pass! 514 | ========== END entry-dynamic.exe fflush_exit ========== 515 | ========== START entry-dynamic.exe fgets_eof ========== 516 | Pass! 517 | ========== END entry-dynamic.exe fgets_eof ========== 518 | ========== START entry-dynamic.exe fgetwc_buffering ========== 519 | Pass! 520 | ========== END entry-dynamic.exe fgetwc_buffering ========== 521 | ========== START entry-dynamic.exe fpclassify_invalid_ld80 ========== 522 | Pass! 523 | ========== END entry-dynamic.exe fpclassify_invalid_ld80 ========== 524 | ========== START entry-dynamic.exe ftello_unflushed_append ========== 525 | Pass! 526 | ========== END entry-dynamic.exe ftello_unflushed_append ========== 527 | ========== START entry-dynamic.exe getpwnam_r_crash ========== 528 | Pass! 529 | ========== END entry-dynamic.exe getpwnam_r_crash ========== 530 | ========== START entry-dynamic.exe getpwnam_r_errno ========== 531 | Pass! 532 | ========== END entry-dynamic.exe getpwnam_r_errno ========== 533 | ========== START entry-dynamic.exe iconv_roundtrips ========== 534 | Pass! 535 | ========== END entry-dynamic.exe iconv_roundtrips ========== 536 | ========== START entry-dynamic.exe inet_ntop_v4mapped ========== 537 | Pass! 538 | ========== END entry-dynamic.exe inet_ntop_v4mapped ========== 539 | ========== START entry-dynamic.exe inet_pton_empty_last_field ========== 540 | Pass! 541 | ========== END entry-dynamic.exe inet_pton_empty_last_field ========== 542 | ========== START entry-dynamic.exe iswspace_null ========== 543 | Pass! 544 | ========== END entry-dynamic.exe iswspace_null ========== 545 | ========== START entry-dynamic.exe lrand48_signextend ========== 546 | Pass! 547 | ========== END entry-dynamic.exe lrand48_signextend ========== 548 | ========== START entry-dynamic.exe lseek_large ========== 549 | Pass! 550 | ========== END entry-dynamic.exe lseek_large ========== 551 | ========== START entry-dynamic.exe malloc_0 ========== 552 | Pass! 553 | ========== END entry-dynamic.exe malloc_0 ========== 554 | ========== START entry-dynamic.exe mbsrtowcs_overflow ========== 555 | Pass! 556 | ========== END entry-dynamic.exe mbsrtowcs_overflow ========== 557 | ========== START entry-dynamic.exe memmem_oob_read ========== 558 | Pass! 559 | ========== END entry-dynamic.exe memmem_oob_read ========== 560 | ========== START entry-dynamic.exe memmem_oob ========== 561 | Pass! 562 | ========== END entry-dynamic.exe memmem_oob ========== 563 | ========== START entry-dynamic.exe mkdtemp_failure ========== 564 | Pass! 565 | ========== END entry-dynamic.exe mkdtemp_failure ========== 566 | ========== START entry-dynamic.exe mkstemp_failure ========== 567 | Pass! 568 | ========== END entry-dynamic.exe mkstemp_failure ========== 569 | ========== START entry-dynamic.exe printf_1e9_oob ========== 570 | Pass! 571 | ========== END entry-dynamic.exe printf_1e9_oob ========== 572 | ========== START entry-dynamic.exe printf_fmt_g_round ========== 573 | Pass! 574 | ========== END entry-dynamic.exe printf_fmt_g_round ========== 575 | ========== START entry-dynamic.exe printf_fmt_g_zeros ========== 576 | Pass! 577 | ========== END entry-dynamic.exe printf_fmt_g_zeros ========== 578 | ========== START entry-dynamic.exe printf_fmt_n ========== 579 | Pass! 580 | ========== END entry-dynamic.exe printf_fmt_n ========== 581 | ========== START entry-dynamic.exe pthread_robust_detach ========== 582 | Pass! 583 | ========== END entry-dynamic.exe pthread_robust_detach ========== 584 | ========== START entry-dynamic.exe pthread_cond_smasher ========== 585 | Pass! 586 | ========== END entry-dynamic.exe pthread_cond_smasher ========== 587 | ========== START entry-dynamic.exe pthread_condattr_setclock ========== 588 | Pass! 589 | ========== END entry-dynamic.exe pthread_condattr_setclock ========== 590 | ========== START entry-dynamic.exe pthread_exit_cancel ========== 591 | Pass! 592 | ========== END entry-dynamic.exe pthread_exit_cancel ========== 593 | ========== START entry-dynamic.exe pthread_once_deadlock ========== 594 | Pass! 595 | ========== END entry-dynamic.exe pthread_once_deadlock ========== 596 | ========== START entry-dynamic.exe pthread_rwlock_ebusy ========== 597 | Pass! 598 | ========== END entry-dynamic.exe pthread_rwlock_ebusy ========== 599 | ========== START entry-dynamic.exe putenv_doublefree ========== 600 | Pass! 601 | ========== END entry-dynamic.exe putenv_doublefree ========== 602 | ========== START entry-dynamic.exe regex_backref_0 ========== 603 | Pass! 604 | ========== END entry-dynamic.exe regex_backref_0 ========== 605 | ========== START entry-dynamic.exe regex_bracket_icase ========== 606 | Pass! 607 | ========== END entry-dynamic.exe regex_bracket_icase ========== 608 | ========== START entry-dynamic.exe regex_ere_backref ========== 609 | Pass! 610 | ========== END entry-dynamic.exe regex_ere_backref ========== 611 | ========== START entry-dynamic.exe regex_escaped_high_byte ========== 612 | Pass! 613 | ========== END entry-dynamic.exe regex_escaped_high_byte ========== 614 | ========== START entry-dynamic.exe regex_negated_range ========== 615 | Pass! 616 | ========== END entry-dynamic.exe regex_negated_range ========== 617 | ========== START entry-dynamic.exe regexec_nosub ========== 618 | Pass! 619 | ========== END entry-dynamic.exe regexec_nosub ========== 620 | ========== START entry-dynamic.exe rewind_clear_error ========== 621 | Pass! 622 | ========== END entry-dynamic.exe rewind_clear_error ========== 623 | ========== START entry-dynamic.exe rlimit_open_files ========== 624 | Pass! 625 | ========== END entry-dynamic.exe rlimit_open_files ========== 626 | ========== START entry-dynamic.exe scanf_bytes_consumed ========== 627 | Pass! 628 | ========== END entry-dynamic.exe scanf_bytes_consumed ========== 629 | ========== START entry-dynamic.exe scanf_match_literal_eof ========== 630 | Pass! 631 | ========== END entry-dynamic.exe scanf_match_literal_eof ========== 632 | ========== START entry-dynamic.exe scanf_nullbyte_char ========== 633 | Pass! 634 | ========== END entry-dynamic.exe scanf_nullbyte_char ========== 635 | ========== START entry-dynamic.exe setvbuf_unget ========== 636 | Pass! 637 | ========== END entry-dynamic.exe setvbuf_unget ========== 638 | ========== START entry-dynamic.exe sigprocmask_internal ========== 639 | Pass! 640 | ========== END entry-dynamic.exe sigprocmask_internal ========== 641 | ========== START entry-dynamic.exe sscanf_eof ========== 642 | Pass! 643 | ========== END entry-dynamic.exe sscanf_eof ========== 644 | ========== START entry-dynamic.exe statvfs ========== 645 | Pass! 646 | ========== END entry-dynamic.exe statvfs ========== 647 | ========== START entry-dynamic.exe strverscmp ========== 648 | Pass! 649 | ========== END entry-dynamic.exe strverscmp ========== 650 | ========== START entry-dynamic.exe syscall_sign_extend ========== 651 | Pass! 652 | ========== END entry-dynamic.exe syscall_sign_extend ========== 653 | ========== START entry-dynamic.exe tls_get_new_dtv ========== 654 | Pass! 655 | ========== END entry-dynamic.exe tls_get_new_dtv ========== 656 | ========== START entry-dynamic.exe uselocale_0 ========== 657 | Pass! 658 | ========== END entry-dynamic.exe uselocale_0 ========== 659 | ========== START entry-dynamic.exe wcsncpy_read_overflow ========== 660 | Pass! 661 | ========== END entry-dynamic.exe wcsncpy_read_overflow ========== 662 | ========== START entry-dynamic.exe wcsstr_false_negative ========== 663 | Pass! 664 | ========== END entry-dynamic.exe wcsstr_false_negative ========== 665 | """ 666 | 667 | def parse_libctest(output): 668 | ans = {} 669 | key = "" 670 | for line in output.split("\n"): 671 | if "START entry-static.exe" in line: 672 | key = "libctest static " + line.split(" ")[3] 673 | elif "START entry-dynamic.exe" in line: 674 | key = "libctest dynamic " + line.split(" ")[3] 675 | if line == "Pass!" and key != "": 676 | ans[key] = 1 677 | return ans 678 | 679 | serial_out = sys.stdin.read() 680 | libctest_baseline_out = parse_libctest(libctest_baseline) 681 | libctest_output = parse_libctest(serial_out) 682 | for k in libctest_baseline_out.keys(): 683 | if k not in libctest_output: 684 | libctest_output[k] = 0 685 | 686 | results = [{ 687 | "name": k, 688 | "pass": v, 689 | "total": 1, 690 | "score": v, 691 | } for k, v in libctest_output.items()] 692 | print(json.dumps(results)) 693 | -------------------------------------------------------------------------------- /judge/judge_lua.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | import sys 4 | 5 | cmds = """ 6 | date.lua 7 | file_io.lua 8 | max_min.lua 9 | random.lua 10 | remove.lua 11 | round_num.lua 12 | sin30.lua 13 | sort.lua 14 | strings.lua 15 | """ 16 | 17 | serial_out = sys.stdin.read() 18 | result = {} 19 | pattern = re.compile(r"testcase (.+) (\bsuccess\b|\bfail\b)") 20 | results = pattern.findall(serial_out) 21 | results = {x[0].strip(): x[1] == 'success' for x in results} 22 | 23 | for line in cmds.split('\n'): 24 | line = line.strip() 25 | if not line: 26 | continue 27 | if f"lua {line}" not in results.keys(): 28 | results[f"lua {line}"] = False 29 | 30 | results = [{ 31 | "name": k, 32 | "pass": 1 if v else 0, 33 | "all": 1, 34 | "score": 1 if v else 0, 35 | } 36 | for k, v in results.items() 37 | ] 38 | 39 | print(json.dumps(results)) -------------------------------------------------------------------------------- /judge/lmbench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! command -v lmbench_all &> /dev/null; then 4 | lmbench_all="" 5 | have_lmbench="" 6 | else 7 | have_lmbench="yes" 8 | fi 9 | 10 | 11 | run_test() { 12 | local test_name=$1 13 | 14 | if [ -z "$have_lmbench" ]; then 15 | local command="./$2" 16 | result=$($command 2>&1 | tail -n 1) 17 | else 18 | local command=$2 19 | result=$($command 2>&1 | tail -n 1) 20 | fi 21 | number=$(echo "$result" | grep -oP '\d+\.\d+') 22 | 23 | if [[ "$2" == *lat_fs* ]]; then 24 | # Assuming the output is stored in a variable or command result 25 | output="10k 581 105675 191452" 26 | 27 | # Extract the two numbers (105675 and 191452) 28 | num1=$(echo $result | awk '{print $3}') 29 | num2=$(echo $result | awk '{print $4}') 30 | 31 | # Perform the addition 32 | number=$((num1 + num2)) 33 | fi 34 | 35 | if [[ "$2" == *lat_mmap* || "$2" == *bw_file_rd* 36 | || "$2" == *bw_mmap_rd* ]]; then 37 | number=$(echo "$result" | awk '{print $1}') 38 | fi 39 | if [ -z "$number" ]; then 40 | number=$(echo "$result" | awk '{print $1}') 41 | fi 42 | echo "$test_name:$number" 43 | } 44 | 45 | 46 | run_test "1:syscall null latency (micro second)" "lat_syscall -P 1 null" 47 | run_test "2:syscall read latency (micro second)" "lat_syscall -P 1 read" 48 | run_test "3:syscall write latency (micro second)" "lat_syscall -P 1 write" 49 | run_test "4:syscall stat latency (micro second)" "lat_syscall -P 1 stat" 50 | run_test "5:syscall fstat latency (micro second)" "lat_syscall -P 1 fstat" 51 | run_test "6:syscall open latency (micro second)" "lat_syscall -P 1 open" 52 | run_test "7:select latency (micro second)" "lat_select -n 100 -P 1 file" 53 | run_test "8:sig install latency (micro second)" "lat_sig -P 1 install" 54 | run_test "9:sig catch latency (micro second)" "lat_sig -P 1 catch" 55 | run_test "10:sig prot latency (micro second)" "lat_sig -P 1 prot lat_sig" 56 | run_test "11:pipe latency (micro second)" "lat_pipe -P 1" 57 | run_test "12:proc fork latency (micro second)" "lat_proc -P 1 fork" 58 | run_test "13:proc exec latency (micro second)" "lat_proc -P 1 exec" 59 | run_test "14:proc shell latency (micro second)" "lat_proc -P 1 shell" 60 | run_test "15:fs write bandwidth (KB/sec)" "lmdd of=/var/tmp/XXX move=1m fsync=1 print=3" 61 | run_test "16:pagefault latency (micro second)" "lat_pagefault -P 1 /var/tmp/XXX" 62 | run_test "17:mmap latency (micro second)" "lat_mmap -P 1 512k /var/tmp/XXX" 63 | run_test "18:pipe bandwidth (KB/sec)" "bw_pipe -P 1" 64 | run_test "19:file system latency (creations+deletes per second)" "lat_fs /var/tmp" 65 | run_test "20:512k file read ioonly (megabytes per second)" "bw_file_rd -P 1 512k io_only /var/tmp/XXX" 66 | run_test "21:512k file read open2close (megabytes per second)" "bw_file_rd -P 1 512k open2close /var/tmp/XXX" 67 | run_test "22:512k mmap read mmaponly (megabytes per second)" "bw_mmap_rd -P 1 512k mmap_only /var/tmp/XXX" 68 | run_test "23:512k mmap read mmaponly (megabytes per second)" "bw_mmap_rd -P 1 512k open2close /var/tmp/XXX" 69 | run_test "24:context switch latency (micro second when there are 96 processes)" "lat_ctx -P 1 -s 32 2 4 8 16 24 32 64 96" 70 | -------------------------------------------------------------------------------- /lmbench/lmbench.md: -------------------------------------------------------------------------------- 1 | # lmbench 测试用例 2 | 3 | ## 题目描述 4 | 5 | lmbench 是一个用于测量 Unix 系统性能的基准测试工具,最初发布于 1995 年,作者是Larry McVoy,时任 Sun Microsystems 工程师,也是 BitKeeper 等工具的作者。Sun Microsystems 在 90 年代主导工作站和服务器市场,LMbench 应运而生以解决系统级性能评估的需求。它旨在提供一套微基准测试工具,帮助开发者理解硬件和操作系统的底层性能特征。 6 | 7 | 本测试使用的是lmbench 3-增加了对现代多核处理器、大规模内存和新型文件系统的支持。LMbench 通过微基准测试(Microbenchmarks)测量系统的延迟和带宽,涵盖以下核心模块: 8 | 9 | - **处理器与内存** 10 | 11 | - **上下文切换**:进程/线程切换的时间开销。 12 | - **内存延迟**:不同层级(L1/L2 缓存、主存)的访问延迟。 13 | - **整数/浮点运算**:基础计算性能。 14 | - **文件系统** 15 | 16 | - **文件读写**:小文件和大文件的顺序/随机读写速度。 17 | - **文件创建/删除**:操作系统的文件管理效率。 18 | - **网络** 19 | 20 | - **TCP/UDP 延迟**:本地回环和远程通信的延迟。 21 | - **带宽测试**:最大传输速率。 22 | - **进程与线程** 23 | 24 | - **进程创建**:`fork()` + `exec()` 的开销。 25 | - **信号处理**:信号传递与响应时间。 26 | - **管道/套接字通信**:进程间通信(IPC)效率。 27 | - **其他** 28 | 29 | - **系统调用开销**:如 `getpid()`、`open()`/`close()`。 30 | - **内存带宽**:如 `memset`、`memcpy` 的速度。 31 | 32 | 在我们的测试中,涉及的测试项目参见**评分依据**。 33 | 34 | ## 编译方法 35 | 36 | 执行以下命令自动测试并编译lmbench: 37 | 38 | ```bash 39 | make build 40 | make oscomp 41 | ``` 42 | 43 | 然后执行[脚本](https://github.com/oscomp/testsuits-for-oskernel/blob/pre-2025/scripts/lmbench/lmbench_testcode.sh),获得输出。 44 | 45 | ## 评分依据 46 | 47 | | 测试项目 | 单位 | 预期范围 | 评分原则 | 48 | | -------------------------------- | ----------------- | --------------- | -------- | 49 | | 空系统调用操作延迟 | 微秒 | 0.0757 - 2.0 | 越小越好 | 50 | | 读系统调用延迟 | 微秒 | 0.1 - 2.2 | 越小越好 | 51 | | 写系统调用延迟 | 微秒 | 0.1 - 2.2 | 越小越好 | 52 | | stat 系统调用延迟 | 微秒 | 0.5 - 2.1 | 越小越好 | 53 | | fstat 系统调用延迟 | 微秒 | 0.15 - 2.0 | 越小越好 | 54 | | open 系统调用延迟 | 微秒 | 1.0 - 3.0 | 越小越好 | 55 | | select 系统调用延迟 | 微秒 | 0.5 - 2.7 | 越小越好 | 56 | | 信号安装延迟 | 微秒 | 0.1 - 2.3 | 越小越好 | 57 | | 信号捕获延迟 | 微秒 | 0.8 - 2.0 | 越小越好 | 58 | | 信号保护延迟 | 微秒 | 0.3 - 2.5 | 越小越好 | 59 | | 管道延迟 | 微秒 | 4 - 20 | 越小越好 | 60 | | 进程 fork 延迟 | 微秒 | 94 - 200 | 越小越好 | 61 | | 进程 exec 延迟 | 微秒 | 101 - 300 | 越小越好 | 62 | | 进程 shell 延迟 | 微秒 | 300 - 2000 | 越小越好 | 63 | | 文件系统写入带宽 | KB/秒 | 3000 - 200000 | 越大越好 | 64 | | 页面错误延迟 | 微秒 | 0.1 - 3.2 | 越小越好 | 65 | | mmap 延迟 | 微秒 | 0.3 - 10 | 越小越好 | 66 | | 管道带宽 | KB/秒 | 1000 - 10000 | 越大越好 | 67 | | 文件系统延迟 | 每秒创建+删除次数 | 100000 - 300000 | 越大越好 | 68 | | 512k 文件读取速度(仅 I/O) | MB/秒 | 0.5 - 2.0 | 越大越好 | 69 | | 512k 文件读取速度(打开至关闭) | MB/秒 | 0.5 - 2.2 | 越大越好 | 70 | | 512k mmap 读取速度(mmaponly) | MB/秒 | 0.5 - 3.0 | 越大越好 | 71 | | 512k mmap 读取速度(open2close) | MB/秒 | 0.5 - 3.0 | 越大越好 | 72 | | 上下文切换延迟(96 进程时) | 微秒 | 1 - 5.0 | 越小越好 | 73 | --------------------------------------------------------------------------------