From 1e58af5f3b0f09ea67f9f96e859713ca483c3228 Mon Sep 17 00:00:00 2001 From: pvouy64kf <2098717229@qq.com> Date: Mon, 4 Jul 2022 11:48:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E7=BA=BF=E7=A8=8B=E5=86=85?= =?UTF-8?q?=E5=AD=98=E6=B5=8B=E8=AF=95=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memtest.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 memtest.c diff --git a/memtest.c b/memtest.c new file mode 100644 index 0000000..5dd6bd4 --- /dev/null +++ b/memtest.c @@ -0,0 +1,169 @@ +#include "pthread.h" + +/* + * memtest.c + * simple memory test + * Copyright (C) 2008 All rights reserved. + * + */ + +void memoryTest(void * arg) +{ + int *loc = (int *)arg; + int start_p = *loc; + int end_p = *(loc + 1); + int times = *(loc + 2); + int *totalCorrect_p = loc + 3; // 主线程中记录测试成功的内存单元总个数的变量的指针 + int *totalTimes_p = loc + 4; // 主线程中记录测试内存单元总个数的变量的指针 + char FailFlag = '0'; // 本次测试是否通过的标志,字符‘0’表示通过,‘1’表示测试没有通过 + char random = rand(); + char testData[5] = {0x00, 0xFF, 0x55, 0xAA, random}; // 用于测试的五数据,最后一个是没有被初始化的随机数random没有初始化 + char *i = (char *)start_p; + int j = 0; + int k = 0; + + for( ; i <= (char *)end_p; i++) + { + for(j = 0; j < times; j++) + { + if(*(loc + 5) == 1) + pthread_exit(0); + for(k = 0; k < 5; k++) // 五种数据都通过才算是通过测试 + { + if(*(loc + 5) == 1) // 如果主线程发了终止线程信号,要立刻终止该线程 + pthread_exit(0); + + *i = testData[k]; + if(*i != testData[k]) + { + FailFlag = '1'; + break; + } + } + if(FailFlag == '1')// times次测试中有一次不成功就算是没有通过测试 + break; + } + if(*(loc + 5) == 1) // 如果主线程发了终止线程信号,要立刻终止该线程 + pthread_exit(0); + + if(FailFlag == '0') // 通过时候测试通过的内存单元个数加一 + (*totalCorrect_p)++; + (*totalTimes_p)++; // 完成的测试内存单元数要加一 + FailFlag = '0';// 标志复位 + } + pthread_exit(0); // 线程安全退出 + +} + +int main() +{ + char *command[6] = {"thread", "times", "go", "status", "abort", "exit"};// 所有的命令 + char *ThisCommand; + int TotalThreadsNum = 0; // 线程总数 + int times = 0; // 测试的次数 + pthread_t threads[64] = {0}; // 设置最大64个线程足够使用 + int addrSize = 0; + + // 每个线程有五个参数需要知道: + // 开始测试地址,结束地址,每个地址测试次数,测试正常的内存单元个数,测试内存单元的总个数、主线程是否发出了终止线程的信号 + // 把第一个参数地址传递过去,其他的四个通过地址增加来共享主线程的数据,从而得到参数或者对参数内容进行读写 + + int args[64][6] = {{0}}; + int i = 0; + int value = 0; // 等待线程结束的返回之存放在这个变量中 + + char *testAddr = (char *)malloc(0x000FFFFF); // 申请1MB内存用于测试 + + while(1) + { + printf(">>>>"); + fflush(stdout); + scanf("%s",ThisCommand); + if( strcmp(ThisCommand, command[0]) == 0 ) // thread number + { + scanf("%d",&TotalThreadsNum); + // 读到thread number后设置每个线程需要的开始和结束地址的参数 + // 创建number个线程 + + addrSize = 0x000FFFFF / TotalThreadsNum; + args[0][0] = (int)testAddr; + args[0][1] = args[0][0] + addrSize - 1; + for(i = 1; i < TotalThreadsNum - 1; i++) + { + args[i][0] = args[i - 1][1] + 1; + args[i][1] = addrSize + args[i][0] - 1; + } + args[i][0] = args[i - 1][1] + 1; + args[i][1] = (int)testAddr + 0x000FFFFF - 1; // 测试结束的地址 + printf("Will use %d threads.\n",TotalThreadsNum); + continue; + } + + if( strcmp(ThisCommand, command[1]) == 0 ) // times + { + scanf("%d",×); + for(i = 0; i < TotalThreadsNum; i++) + { + args[i][2] = times; + } + printf("Each byte will be tested by %d times.\n",times); + continue; + } + if( strcmp(ThisCommand, command[2]) == 0 ) // go + { + for(i = 0; i < TotalThreadsNum; i++) // 创建线程 + pthread_create(&threads[i], NULL, (void *)memoryTest, (void *)args[i]); + continue; + } + if( strcmp(ThisCommand, command[3]) == 0 ) // status + { + for(i = 0; i < TotalThreadsNum; i++) + { + // 为了简化操作,如果本次已经测试的总内存单元数(放在args[i][4])等于分配的总个数或者线程状态被设置为'1' + // 即可以简单的认为表示本线程已经结束 + if( args[i][4] == args[i][1] - args[i][0] + 1 || args[i][5] == 1 ) + printf("Thread %d has exited.(%p-%p, %d/%d/%d)\n", i, args[i][0], args[i][1], args[i][3], args[i][4], args[i][1] - args[i][0] + 1); + else + printf("Thread %d is running.(%p-%p, %d/%d/%d)\n", i, args[i][0], args[i][1], args[i][3], args[i][4], args[i][1] - args[i][0] + 1); + } + continue; + } + if( strcmp(ThisCommand, command[4]) == 0 ) // abort + { + // 线程终止状态设置为'1',表示线程被人为退出 + for(i = 0; i < TotalThreadsNum; i++) + args[i][5] = 1; + continue; + } + if( strcmp(ThisCommand, command[5]) == 0 ) // exit + { + for(i = 0; i < TotalThreadsNum; i++) // 给每个线程的标志为设置为1,让其退出 + { + args[i][5] = 1; // 线程终止状态设置为'1',表示线程被人为退出 + } + + // 标志为设置为1之后要等待每个线程真正的结束,主线程才能退出,否则主线程释放内存 + // 线程再执行的时候会出现严重的错误 + for(i = 0; i < TotalThreadsNum; i++) + { + pthread_join(threads[i], (void *)value); + } + return 0; + } + } + return 0; +} + + + + + + + + + + + + + +