⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiotest.c

📁 Linux Distributed Replication Block Device
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *    Threaded io test * *  Copyright (C) 1999-2000 Mika Kuoppala <miku@iki.fi> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software Foundation, *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   * * */#include "tiotest.h"#include "crc32.h"static const char* versionStr = "tiotest v0.3.3 (C) 1999-2000 Mika Kuoppala <miku@iki.fi>";/*    This is global for easier usage. If you put changing data   in here from threads, be sure to protect it with mutexes.*/ArgumentOptions args;static void * aligned_alloc(ssize_t size){	caddr_t a;	a = mmap((caddr_t )0, size, 	         PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);	if (a == MAP_FAILED)		return NULL;	return a;}static int aligned_free(caddr_t a, ssize_t size){	return munmap(a, size);}int main(int argc, char *argv[]){	ThreadTest test;	int i;	strcpy(args.path[0], DEFAULT_DIRECTORY );	args.pathsCount = 1;	args.fileSizeInMBytes = DEFAULT_FILESIZE;	args.blockSize = DEFAULT_BLOCKSIZE;	args.numThreads = DEFAULT_THREADS;	args.numRandomOps = DEFAULT_RANDOM_OPS;	args.debugLevel = DEFAULT_DEBUG_LEVEL;	args.verbose = 0;	args.terse = 0;	args.consistencyCheckData = 0;	args.syncWriting = 0;	args.rawDrives = 0;	args.showLatency = 1;	args.threadOffset = DEFAULT_RAW_OFFSET;	args.useThreadOffsetForFirstThread = 0;		for(i = 0; i < TESTS_COUNT; i++)		args.testsToRun[i] = 1;	#if (LARGEFILES && USE_MMAP)	printf("warning: LARGEFILES with MMAP needs mmap64 support which is not working yet in tiotest!\n");#endif	parse_args( &args, argc, argv );    	initialize_test( &test );		do_tests( &test );	print_results( &test );	cleanup_test( &test );	return 0;}inline void checkIntZero(int value, char *mess){	if (value <= 0) 	{		printf(mess);		printf("Try 'tiotest -h' for more information.\n");		exit(1);	}}inline void checkLong(long value, char *mess){	if (value < 0) 	{		printf(mess);		printf("Try 'tiotest -h' for more information\n");		exit(1);	}}void parse_args( ArgumentOptions* args, int argc, char *argv[] ){	int c;	int once = 0;	while (1)	{		c = getopt( argc, argv, "f:b:d:t:r:D:k:o:hLRTWSOc");		if (c == -1)			break;			switch (c)		{		case 'f':			args->fileSizeInMBytes = atoi(optarg);			checkIntZero(args->fileSizeInMBytes, "Wrong file size\n");			break;	    		case 'b':			args->blockSize = atoi(optarg);			checkIntZero(args->blockSize, "Wrong block size\n");			break;	    		case 'd':			if (args->pathsCount < MAX_PATHS) 			{				if (!once) 				{					args->pathsCount = 0;           					once = 1;				}				strcpy(args->path[args->pathsCount++], optarg);			}			break;	    		case 't':			args->numThreads = atoi(optarg);			checkIntZero(args->numThreads, "Wrong number of threads\n");			break;	    		case 'r':			args->numRandomOps = atoi(optarg);			checkIntZero(args->numRandomOps, "Wrong number of random I/O operations\n");			break;	    	    	case 'L':			args->showLatency = FALSE;			break;	    		case 'T':			args->terse = TRUE;			break;		case 'W':			args->sequentialWriting = TRUE;			break;					case 'S':			args->syncWriting = TRUE;			break;					case 'R':			args->rawDrives = TRUE;			break;		case 'c':			args->consistencyCheckData = TRUE;			break;		case 'h':			print_help_and_exit();			break;				case 'D':			args->debugLevel = atoi(optarg);			break;				case 'o':			args->threadOffset = atol(optarg);			checkLong(args->threadOffset, "Wrong offset between threads\n");			break;					case 'O':			args->useThreadOffsetForFirstThread = TRUE;			break;					case 'k':		{			int i = atoi(optarg);			if (i < TESTS_COUNT) 			{				args->testsToRun[i] = 0;				break;			}			else				printf("Wrong test number %d\n", i);			/* Go through */		}		case '?':		default:			printf("Try 'tiotest -h' for more information\n");			exit(1);			break;		}	}}void initialize_test( ThreadTest *d ){	int i;	int pathLoadBalIdx = 0;	toff_t offs, cur_offs[KBYTE] = {0};	memset( d, 0, sizeof(ThreadTest) );    	d->numThreads = args.numThreads; 	for(i = 0; i < d->numThreads; i++)	{		d->threads = calloc( d->numThreads, sizeof(ThreadData) );		if( d->threads == NULL )		{			perror("Error allocating memory");			exit(-1);		}	}	/* Initializing thread data */	if (args.rawDrives) 	{		if (args.threadOffset != 0) 		{			offs = (args.threadOffset + args.fileSizeInMBytes) * MBYTE;			if (args.useThreadOffsetForFirstThread) 			{				int k;				for(k = 0; k < KBYTE; k++)					cur_offs[k] = args.threadOffset * MBYTE;			}		}		else			offs = args.fileSizeInMBytes * MBYTE;	}	else		offs = 0;	for(i = 0; i < d->numThreads; i++)	{		d->threads[i].myNumber = i;		d->threads[i].blockSize = args.blockSize;		d->threads[i].numRandomOps = args.numRandomOps;		d->threads[i].fileSizeInMBytes = args.fileSizeInMBytes;		if (args.rawDrives)		{			d->threads[i].fileOffset = cur_offs[pathLoadBalIdx];			cur_offs[pathLoadBalIdx] += offs;			sprintf(d->threads[i].fileName, "%s",				args.path[pathLoadBalIdx++]);		}		else		{			d->threads[i].fileOffset = 0;			sprintf(d->threads[i].fileName, "%s/_%d_tiotest.%d",				args.path[pathLoadBalIdx++], getpid(), i);		}				if( pathLoadBalIdx >= args.pathsCount )			pathLoadBalIdx = 0;		pthread_attr_init( &(d->threads[i].thread_attr) );		pthread_attr_setscope(&(d->threads[i].thread_attr),				      PTHREAD_SCOPE_SYSTEM);		d->threads[i].buffer = aligned_alloc( d->threads[i].blockSize );		if( d->threads[i].buffer == NULL )		{			perror("Error allocating memory");			exit(-1);		}		if( args.consistencyCheckData )		{			int j;			const unsigned long bsize = d->threads[i].blockSize;			unsigned char *b = d->threads[i].buffer;			for(j = 0; j < bsize; j++)				b[j] = rand() & 0xFF;			d->threads[i].bufferCrc = crc32(b, bsize, 0);		}	}}void print_option(const char* s, 		  const char* desc, 		  const char* def){	printf("  %s          %s", s, desc);    	if(def)		printf(" (default: %s)", def);	printf("\n");   }char *my_int_to_string(int a){	static char tempBuffer[128];	sprintf(tempBuffer, "%d", a);	return tempBuffer;}void print_help_and_exit(){	printf("%s\n", versionStr);	printf("Usage: tiotest [options]\n");	print_option("-f", "Filesize per thread in MBytes",		     my_int_to_string(DEFAULT_FILESIZE));	print_option("-b", "Blocksize to use in bytes",		     my_int_to_string(DEFAULT_BLOCKSIZE));	print_option("-d", "Directory for test files", 		     DEFAULT_DIRECTORY);	print_option("-t", "Number of concurrent test threads",		     my_int_to_string(DEFAULT_THREADS));	print_option("-r", "Random I/O operations per thread", 		     my_int_to_string(DEFAULT_RANDOM_OPS));		     	print_option("-o", "Offset in Mb on disk between threads. Use with -R option",		     0);		print_option("-k", "Skip test number n. Could be used several times.", 0);	  		print_option("-L", "Hide latency output", 0);	  		print_option("-R", "Use raw devices. Set device name with -d option", 0);	print_option("-T", "More terse output", 0);	print_option("-W", "Do writing phase sequentially", 0);		print_option("-S", "Do writing synchronously", 0);		print_option("-O", "Use offset from -o option for first thread. Use with -R option",		     0);	print_option("-c", 		     "Consistency check data (will slow io and raise cpu%)",		     0);		print_option("-D", "Debug level",		     my_int_to_string(DEFAULT_DEBUG_LEVEL));	print_option("-h", "Print this help and exit", 0);	exit(1);}void cleanup_test( ThreadTest *d ){	int i;	for(i = 0; i < d->numThreads; i++)	{		if (!args.rawDrives)		unlink(d->threads[i].fileName);		aligned_free( d->threads[i].buffer, d->threads[i].blockSize );		d->threads[i].buffer = 0;			pthread_attr_destroy( &(d->threads[i].thread_attr) );	}	free(d->threads);    	d->threads = 0;}void wait_for_threads( ThreadTest *d ){	int i;	for(i = 0; i < d->numThreads; i++)		pthread_join(d->threads[i].thread, NULL);	}void do_tests( ThreadTest *thisTest ){	Timings *timeWrite       = &(thisTest->totalTimeWrite);	Timings *timeRandomWrite = &(thisTest->totalTimeRandomWrite);	Timings *timeRead        = &(thisTest->totalTimeRead);	Timings *timeRandomRead  = &(thisTest->totalTimeRandomRead);	timer_init( timeWrite );	timer_init( timeRandomWrite );	timer_init( timeRead );	timer_init( timeRandomRead );	/*	  Write testing 	*/    	if (args.testsToRun[WRITE_TEST])		do_test( thisTest, WRITE_TEST, args.sequentialWriting,			timeWrite,  "Waiting write threads to finish...");	/*	  RandomWrite testing 	*/    	if (args.testsToRun[RANDOM_WRITE_TEST])		do_test( thisTest, RANDOM_WRITE_TEST, FALSE, timeRandomWrite,			"Waiting random write threads to finish...");	/*	  Read testing 	*/    	if (args.testsToRun[READ_TEST])		do_test( thisTest, READ_TEST, FALSE, timeRead,			"Waiting read threads to finish..." );	/*	  RandomRead testing 	*/	if (args.testsToRun[RANDOM_READ_TEST])		do_test( thisTest, RANDOM_READ_TEST, FALSE, timeRandomRead,			"Waiting random read threads to finish...");}typedef struct {	volatile int *child_status;	TestFunc fn;	ThreadData *d;	volatile int *pstart;} StartData;void* start_proc( void *data ){	StartData *sd = (StartData*)data;	*sd->child_status = getpid();	if (sd->pstart != NULL)		while (*sd->pstart == 0) sleep(0);	return sd->fn(sd->d);}void do_test( ThreadTest *test, int testCase, int sequential,	Timings *t, char *debugMessage ){	int i;	volatile int *child_status;	StartData *sd;	int synccount;	volatile int start = 0;		child_status = (volatile int *)calloc(test->numThreads, sizeof(int));	if (child_status == NULL) 	{		perror("Error allocating memory");		return;	}		sd = (StartData*)calloc(test->numThreads, sizeof(StartData));	if (sd == NULL) 	{		perror("Error allocating memory");		free((int*)child_status);		return;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -