|
|
@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
#define __LIBRARY__
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "pthread.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define TIMES 1
|
|
|
|
|
|
|
|
#define THREAD 2
|
|
|
|
|
|
|
|
#define GO 3
|
|
|
|
|
|
|
|
#define STATUS 4
|
|
|
|
|
|
|
|
#define ABORT 5
|
|
|
|
|
|
|
|
#define EXIT 6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct com
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char string[20];
|
|
|
|
|
|
|
|
int value;
|
|
|
|
|
|
|
|
int number;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct com command;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct thread_args
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char* start_addr;
|
|
|
|
|
|
|
|
int size;
|
|
|
|
|
|
|
|
int times;
|
|
|
|
|
|
|
|
int finished;
|
|
|
|
|
|
|
|
int abort;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct thread_args args[64]={};
|
|
|
|
|
|
|
|
pthread_t threads[64] = {};
|
|
|
|
|
|
|
|
int fail = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* test_mem(void *thread_arg);
|
|
|
|
|
|
|
|
int get_command(void);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int i,j,k;
|
|
|
|
|
|
|
|
int first=0,second=0,third=0;
|
|
|
|
|
|
|
|
int num_times = 0;
|
|
|
|
|
|
|
|
int num_thread = 0;
|
|
|
|
|
|
|
|
int size=0;
|
|
|
|
|
|
|
|
void *value_ptr[64]={};
|
|
|
|
|
|
|
|
char* start_addr = NULL;
|
|
|
|
|
|
|
|
char* mem_addr = (char *)malloc(0x100000);
|
|
|
|
|
|
|
|
if(!mem_addr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("Error:Memory is not enough!\n");
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf(">>>");
|
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
get_command();
|
|
|
|
|
|
|
|
switch (command.value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case TIMES:
|
|
|
|
|
|
|
|
num_times = command.number;
|
|
|
|
|
|
|
|
printf("Each memory unit will be tested by %d times.\n",num_times);
|
|
|
|
|
|
|
|
first = 1;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case THREAD:
|
|
|
|
|
|
|
|
num_thread = command.number;
|
|
|
|
|
|
|
|
size = 0x100000 / num_thread;
|
|
|
|
|
|
|
|
start_addr = mem_addr;
|
|
|
|
|
|
|
|
for(i=0;i<num_thread;i++) /*线程参数初始化*/
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
args[i].start_addr = start_addr;
|
|
|
|
|
|
|
|
args[i].size = size;
|
|
|
|
|
|
|
|
args[i].finished = 0;
|
|
|
|
|
|
|
|
args[i].abort = 0;
|
|
|
|
|
|
|
|
start_addr = start_addr + size;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
args[num_thread-1].size += (0x100000 % num_thread);
|
|
|
|
|
|
|
|
printf("%d threads will be set.\n",num_thread);
|
|
|
|
|
|
|
|
second = 1;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case GO:
|
|
|
|
|
|
|
|
if(first == 1 && second == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(i=0;i<num_thread;i++) /*对线程参数初始化,并调用pthread_create创建工作线程*/
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
args[i].finished = 0;
|
|
|
|
|
|
|
|
args[i].times = num_times;
|
|
|
|
|
|
|
|
pthread_create(&threads[i],NULL,(void *)test_mem,(void *)(&(args[i])));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
third = 1;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("测试参数不完成,线程初始化未完成!\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
case STATUS: /*打印线程执行信息*/
|
|
|
|
|
|
|
|
if(third == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(i=0;i<num_thread;i++)
|
|
|
|
|
|
|
|
printf("Thread:%d, testSize:%d, testedSize:%d, Ratio:%f\n", i, args[i].size, args[i].finished, (float)args[i].finished / (float)args[i].size);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case ABORT:
|
|
|
|
|
|
|
|
if(second == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(i=0;i<num_thread;i++)
|
|
|
|
|
|
|
|
args[i].abort = 1;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
case EXIT: /*停止测试并退出程序*/
|
|
|
|
|
|
|
|
if(second == 1 && third == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(i=0;i<num_thread;i++)
|
|
|
|
|
|
|
|
args[i].abort = 1;
|
|
|
|
|
|
|
|
for(i=0;i<num_thread;i++)
|
|
|
|
|
|
|
|
pthread_join(threads[i],&value_ptr[i]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* test_mem(void *thread_arg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int i,j,k;
|
|
|
|
|
|
|
|
unsigned int seed=28;
|
|
|
|
|
|
|
|
char data[5] = {};
|
|
|
|
|
|
|
|
char* addr = NULL;
|
|
|
|
|
|
|
|
struct thread_args *arg;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
arg = (struct thread_args *)thread_arg;
|
|
|
|
|
|
|
|
addr = arg->start_addr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fail = 0;
|
|
|
|
|
|
|
|
srand(seed);
|
|
|
|
|
|
|
|
data[0] = 0; /* 对5种数据进行测试 */
|
|
|
|
|
|
|
|
data[1] = 0xFF;
|
|
|
|
|
|
|
|
data[2] = 0x55;
|
|
|
|
|
|
|
|
data[3] = 0xAA;
|
|
|
|
|
|
|
|
data[4] = (char)rand();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0;i<(arg->size);i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(j=0;j<(arg->times);j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(k=0;k<5;k++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
(*addr) = data[k];
|
|
|
|
|
|
|
|
if((*addr) != data[k])
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fail = 1;
|
|
|
|
|
|
|
|
pthread_exit(&fail);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(arg->abort == 1)
|
|
|
|
|
|
|
|
pthread_exit(&fail);
|
|
|
|
|
|
|
|
(arg->finished)++;
|
|
|
|
|
|
|
|
addr++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_exit(&fail);
|
|
|
|
|
|
|
|
return (void *)(&fail);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int get_command(void) /*读取命令函数*/
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
char tmp[20]={};
|
|
|
|
|
|
|
|
int num=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0;i<20;i++) /*命令数据结构初始化*/
|
|
|
|
|
|
|
|
command.string[i] = '\0';
|
|
|
|
|
|
|
|
command.value = 0;
|
|
|
|
|
|
|
|
command.number = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scanf(" %s",tmp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!strcmp(tmp,"times"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
scanf(" %d",&num);
|
|
|
|
|
|
|
|
if(num <= 0 || num > 1000000)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("测试次数参数非法!\n");
|
|
|
|
|
|
|
|
command.value = 0;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
command.number = num;
|
|
|
|
|
|
|
|
command.value = TIMES;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(tmp,"thread"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
scanf(" %d",&num);
|
|
|
|
|
|
|
|
if(num <= 0 || num > 10)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("线程个数参数非法!\n");
|
|
|
|
|
|
|
|
command.value = 0;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
command.number = num;
|
|
|
|
|
|
|
|
command.value = THREAD;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(tmp,"go"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
command.value = GO;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(tmp,"status"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
command.value = STATUS;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(tmp,"abort"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
command.value = ABORT;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(tmp,"exit"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
command.value = EXIT;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(tmp,""))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
command.value = 0;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("命令非法!\n");
|
|
|
|
|
|
|
|
command.value = 0;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|