Integrate SPC-1 with fio, version 2 ready for options

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everyone,

Sorry for 2 posts in one day. I have edited my code since the last post to make it easy to add options once I get some direction about using the options and creating a parameter file. I have attached the patch. All the configurable options are now set in set_spc1_options, which can be modified to read a parameter file.

All advice, comments, suggestions and help welcome.

Kind regards, Mike O'S
From 73d246dd4dcd7ae18c1c6e0ba16737fcd67bad3c Mon Sep 17 00:00:00 2001
From: unknown <mosu001@.(none)>
Date: Wed, 10 Feb 2010 11:06:38 +1300
Subject: [PATCH] Initial integration of open SPC-1 code into fio

---
 spc1_wrapper.c |  660 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 spc1_wrapper.h |   93 ++++++++
 2 files changed, 753 insertions(+), 0 deletions(-)
 create mode 100644 spc1_wrapper.c
 create mode 100644 spc1_wrapper.h

diff --git a/spc1_wrapper.c b/spc1_wrapper.c
new file mode 100644
index 0000000..3c59de5
--- /dev/null
+++ b/spc1_wrapper.c
@@ -0,0 +1,660 @@
+/*
+ * spc1_wrapper.c
+ *
+ *  Created on: 23/12/2009
+ *      Author: Michael
+ */
+
+#ifdef _USE_SPC1
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef _SPC1_H
+#define _SPC1_H
+#include "spc1.h"
+#endif
+
+#include "fio.h"
+
+#include "spc1_wrapper.h"
+
+short use_spc1;
+
+struct spc1_io_s *** iostore;
+
+unsigned ** iocount;
+
+void spc1_io_debug_info(const char *pre, struct spc1_io_s *spc1_io_s_addr) {
+	printf("%s", pre);
+	printf(": address = %d, ASU = %d, R/W = %d, length = %d, bsu stream = %d, bsu = %d, pos = %d, time = %d\n",
+		spc1_io_s_addr,
+		spc1_io_s_addr->asu,
+		spc1_io_s_addr->dir,
+		spc1_io_s_addr->len,
+		spc1_io_s_addr->stream,
+		spc1_io_s_addr->bsu,
+		spc1_io_s_addr->pos,
+		spc1_io_s_addr->when); // .when in 0.1 milliseconds
+	printf("pid = %d\n", getpid());
+	fflush(stdout);
+}
+void fio_io_debug_info(const char *pre, struct io_u *io_u_addr) {
+	printf("%s", pre);
+	printf(": address = %d, R/W = %d, offset = %lld, length = %ld, file %d, ",
+		io_u_addr,
+		io_u_addr->ddir,
+		io_u_addr->offset,
+		io_u_addr->buflen,
+		io_u_addr->file);
+	printf("pid = %d\n", getpid());
+	fflush(stdout);
+}
+
+unsigned spc1_context_from_bsu(unsigned bsu) {
+	int retcode;
+
+	retcode = (bsu + 1) / 100;
+
+	return retcode;
+}
+
+int gen_spc1_ios() {
+	int numContexts = (BSU + 1) / 100;
+	char vbuf[BUFLEN];
+	char pname[] = PNAME;
+
+	struct spc1_io_s nextio;
+	int retcode;
+	unsigned int i, j, bsu, stream, totalio, iops;
+        unsigned long long whenMillis, finalMillis = TOTAL_RUNTIME_MILLIS;
+	char message[BUFLEN];
+	unsigned numStarted, numFinished;
+	int status[BSU][STREAMS];
+
+	printf("Generating SPC-1 workload, num contexts = %d...\n", numContexts);
+
+	printf("Initialising data structures...\n");
+
+       assert( (BEGIN_CONTEXT >= 0) && (BEGIN_CONTEXT <= END_CONTEXT) && (END_CONTEXT <= numContexts) );
+
+	iostore = (struct spc1_io_s ***)malloc(BSU * sizeof(struct spc1_io_s **));
+	iocount = (unsigned **)malloc(BSU * sizeof(unsigned *));
+	for (i=0; i<BSU; i++) {
+		if ( (spc1_context_from_bsu(i) >= BEGIN_CONTEXT) &&
+		     (spc1_context_from_bsu(i) <= END_CONTEXT) ) {
+			iostore[i] = (struct spc1_io_s **)malloc(STREAMS * sizeof(struct spc_io_u *));
+			iocount[i] = (unsigned *)malloc(STREAMS * sizeof(unsigned));
+			for (j=0; j<STREAMS; j++) {
+				iostore[i][j] = (struct spc1_io_s *)malloc(AVG_IOPS*TOTAL_RUNTIME_SECS * sizeof(struct spc1_io_s));
+				iocount[i][j] = 0;
+			}
+		}
+	}
+	memset(status, 0, BSU * STREAMS* sizeof(int)); /* Flags to see if stream started/finished */
+
+
+#ifdef _SPC1_DEBUG
+	printf("SPC-1 checking value of iocount, pid = %d\n", getpid());
+	for (i=0; i<BSU; i++)
+                if ( (spc1_context_from_bsu(i) >= BEGIN_CONTEXT) &&
+                     (spc1_context_from_bsu(i) <= END_CONTEXT) )
+			for (j=0; j<STREAMS; j++)
+				printf("iocount[%d][%d] = %d\n", i, j, iocount[i][j]);
+	fflush(stdout);
+#endif
+
+	printf("Initialising SPC-1 benchmark generator...\n");
+
+    retcode = spc1_init(pname,						// char *m			Name of the program.  Used for error messages.
+	          BSU,							// int b			Number of BSUs.
+	          GB_TO_BLOCK(ASU1_SIZE_GB),	// unsigned int a1	Size of ASU 1 in 4K blocks.
+	          GB_TO_BLOCK(ASU2_SIZE_GB),	// unsigned int a2	Size of ASU 2 in 4K blocks.
+	          GB_TO_BLOCK(ASU3_SIZE_GB),	// unsigned int a3	Size of ASU 3 in 4K blocks.
+	          numContexts,					// int n_contexts	The number of context blocks to allocate
+	          vbuf,							// version	An output buffer where a version string may be written.  If NULL, no version is written.
+	          BUFLEN);						// len	The length of the output buffer.
+
+	if (retcode != SPC1_ENOERR) {
+		printf("Error initialising SPC-1 workload, errcode = %d\n", retcode);
+		return 1;
+	}
+
+	numStarted = numFinished = 0; /* No stream from any BSU has started/finished generating load */
+
+	printf("Initialisation complete!\n");
+
+	/* Generate SPC-1 IOs until the set time has elapsed */
+	printf("Creating SPC-1 workload...\n");
+
+	iops = 0;
+	do {
+		retcode = spc1_next_op_any(&nextio);
+		iops++;
+
+		if (retcode == SPC1_ENOERR) {
+#ifdef _SPC1_DEBUG
+			if ( (iops % IOPS_INFO == 0) || (iops >= IOPS_ALL) ) {
+				sprintf(message, "IOP #%d, context = %d", iops, spc1_context_from_bsu(nextio.bsu)); 
+                        	spc1_io_debug_info(message, &nextio);
+			}
+#endif
+			if ( (spc1_context_from_bsu(nextio.bsu) < BEGIN_CONTEXT) ||
+				 (spc1_context_from_bsu(nextio.bsu) > END_CONTEXT) )
+				continue; /* This bsu is outside the contexts considered */
+
+			bsu = nextio.bsu;
+			stream = nextio.stream;
+			whenMillis = nextio.when / 10;
+
+			if (status[bsu][stream] == -1)
+				continue; /* Nothing to do for this (bsu, stream), go to next IO */
+			else {
+				if (status[bsu][stream] == 0) { /* (bsu, stream) not started yet */
+					status[bsu][stream] = 1; /* Start (bsu, stream) */
+					numStarted++; /* One more (bsu, steam) started */
+				}
+
+#ifdef _SPC1_DEBUG
+	                       if ( (iops % IOPS_INFO == 0) || (iops >= IOPS_ALL) ) {
+					printf("current = %lld, max = %lld\n", whenMillis, finalMillis);
+					fflush(stdout);
+				}
+#endif
+				if (whenMillis > finalMillis) { /* IO happens after time limit */
+					status[bsu][stream] = -1; /* Stop generating for this (bsu, stream) */
+					numFinished++; /* One more (bsu, steam) finished */
+				} else {
+#ifdef _SPC1_DEBUG
+		                       if ( (iops % IOPS_INFO == 0) || (iops >= IOPS_ALL) ) {
+						printf("Adding SPC-1 IO\n");
+						fflush(stdout);
+					}
+#endif
+					iostore[bsu][stream][iocount[bsu][stream]] = nextio; /* Store IO for (bsu, stream) */
+					iocount[bsu][stream]++; /* One more IO for (bsu, stream) */
+				}
+			}
+
+#ifdef _SPC1_DEBUG
+                        if ( (iops % IOPS_INFO == 0) || (iops >= IOPS_ALL) ) {
+				printf("started = %d, finished = %d\n", numStarted, numFinished);
+				fflush(stdout);
+			}
+#endif
+		} else {
+			printf("Problem creating workload.");
+			return 1;
+		}
+
+	} while ( (numStarted > numFinished) || (iops <= MIN_IOPS_GENERATED) );
+
+	totalio = 0;
+	for (i=0; i<BSU; i++)
+	        if ( (spc1_context_from_bsu(i) >= BEGIN_CONTEXT) &&
+                     (spc1_context_from_bsu(i) <= END_CONTEXT) )
+			for (j=0; j<STREAMS;j++) {
+				totalio += iocount[i][j];
+#ifdef _SPC1_DEBUG
+				printf("iocount[%d][%d] = %d\n", i, j, iocount[i][j]);
+				fflush(stdout);
+#endif
+			}
+	printf("totalio = %d, totaltime = %d, average = %g\n",
+			totalio, TOTAL_RUNTIME_SECS, (double)totalio / TOTAL_RUNTIME_SECS / BSU);
+
+    printf("Workload created!\n");
+
+    return 0;
+}
+
+extern char* gen_spc1_file(char *string, unsigned int *global_addr,
+		unsigned int *line_addr, int *bsu_addr, int *str_addr) {
+
+	if (*global_addr) {
+#ifdef _SPC1_DEBUG
+		printf("SPC-1, global section, line = %d\n", *line_addr);
+#endif
+	switch (*line_addr) {
+		case 0:
+			sprintf(string, "[global]");
+			(*line_addr)++;
+			break;
+		case 1:
+			sprintf(string, "rw=randrw");
+			*global_addr = 0;
+			*line_addr = 0;
+#ifdef SINGLE
+			*bsu_addr = BSU_ID_FOR_SINGLE;
+#else
+			*bsu_addr = 0;
+#endif
+			*str_addr = 0;
+			break;
+		}
+
+	} else {
+
+		if (*bsu_addr == BSU_ID_FOR_SINGLE) {
+
+			switch (*line_addr) {
+				case 0:
+					sprintf(string, "[spc_all]");
+					(*line_addr)++;
+					break;
+				case 1:
+					sprintf(string, "write_bw_log=spc_all");
+					(*line_addr)++;
+					break;
+				case 2:
+					sprintf(string, "write_lat_log=spc_all");
+					*str_addr = STREAMS;
+					*bsu_addr = BSU;
+					*line_addr = 0;
+					break;
+				}
+
+		} else if (*bsu_addr == BSU) {
+#ifdef _SPC1_DEBUG
+			printf("SPC-1 generate null string\n");
+#endif
+			return NULL;
+		} else if (iocount[*bsu_addr][*str_addr] > 0) {
+#ifdef _SPC1_DEBUG
+			printf("SPC-1, bsu%d_str%d section, line = %d\n", *bsu_addr, *str_addr, *line_addr);
+#endif
+			switch (*line_addr) {
+			case 0:
+				sprintf(string, "[bsu%d_str%d]", *bsu_addr, *str_addr);
+				(*line_addr)++;
+				break;
+			case 1:
+				sprintf(string, "write_bw_log=spc_bsu%d", *bsu_addr);
+				(*line_addr)++;
+				break;
+			case 2:
+				sprintf(string, "write_lat_log=spc_bsu%d", *bsu_addr);
+				(*str_addr)++;
+				if (*str_addr == STREAMS) {
+					(*bsu_addr)++;
+					*str_addr = 0;
+				}
+				*line_addr = 0;
+				break;
+			}
+		} else {
+			(*str_addr)++;
+			if (*str_addr == STREAMS) {
+				(*bsu_addr)++;
+				*str_addr = 0;
+			}
+			*line_addr = 0;
+		}
+	}
+
+#ifdef _SPC1_DEBUG
+	printf("SPC-1 generate string %s\n", string);
+#endif
+	return string;
+}
+
+int init_spc1_io(struct thread_data *td) {
+	int i, j, k;
+	int fileno;
+
+	if ( (td->bsu >= BSU) || (td->str >= STREAMS) ) return 1;
+#ifdef SINGLE
+#ifdef _SPC1_DEBUG
+		printf("Initialising max_bs...\n");
+#endif
+	td->single_iopos = (unsigned **) malloc(BSU * sizeof(unsigned *));
+	for (i=0; i<BSU; i++)
+		if ( (spc1_context_from_bsu(i) >= BEGIN_CONTEXT) &&
+		     (spc1_context_from_bsu(i) <= END_CONTEXT) ) {
+			td->single_iopos[i] = (unsigned *) malloc(STREAMS * sizeof(unsigned));
+			for (j=0; j<STREAMS; j++) {
+#ifdef _SPC1_DEBUG
+				printf("Initialising position, bsu = %d, str = %d\n", i, j);
+				fflush(stdout);
+#endif
+				td->single_iopos[i][j] = 0;
+				if (td->single_iocount[i][j] < 0) return 1;
+#ifdef _SPC1_DEBUG
+				printf("Checking max size, bsu = %d, str = %d\n", i, j);
+				fflush(stdout);
+//				printf("for %d positions\n", td->single_iocount[i][j]);
+//				fflush(stdout);
+#endif
+				for (k=0; k<td->single_iocount[i][j]; k++) {
+					int rw = td->single_iostore[i][j][k].dir;
+					int bytes = BLOCK_TO_B(td->single_iostore[i][j][k].len);
+
+#ifdef _SPC1_DEBUG
+					printf("IO from bsu = %d, str = %d, pos = %d has size %d\n", i, j, k, bytes);
+#endif
+					if (bytes > td->o.max_bs[rw])
+						td->o.max_bs[rw] = bytes;
+				}
+			}
+		}
+
+#ifdef _SPC1_DEBUG
+		printf("Adding ASU1 file...\n");
+#endif
+	fileno = get_fileno(td, ASU1);
+	if (fileno == -1) {
+		td->o.nr_files++;
+		fileno = add_file(td, ASU1);
+	}
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("ASU1 file could not be added...\n");
+#endif
+		return 1;
+	}
+	if (td_io_open_file(td, td->files[fileno])) {
+#ifdef _SPC1_DEBUG
+		printf("ASU1 file could not be opened...\n");
+#endif
+		return 1;
+	}
+#ifdef _SPC1_DEBUG
+		printf("Adding ASU2 file...\n");
+#endif
+	fileno = get_fileno(td, ASU2);
+	if (fileno == -1) {
+		td->o.nr_files++;
+		fileno = add_file(td, ASU2);
+	}
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("ASU2 file could not be added...\n");
+#endif
+		return 1;
+	}
+	if (td_io_open_file(td, td->files[fileno])) {
+#ifdef _SPC1_DEBUG
+		printf("ASU2 file could not be opened...\n");
+#endif
+		return 1;
+	}
+#ifdef _SPC1_DEBUG
+		printf("Adding ASU3 file...\n");
+#endif
+	fileno = get_fileno(td, ASU3);
+	if (fileno == -1) {
+		td->o.nr_files++;
+		fileno = add_file(td, ASU3);
+	}
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("ASU3 file could not be added...\n");
+#endif
+		return 1;
+	}
+	if (td_io_open_file(td, td->files[fileno])) {
+#ifdef _SPC1_DEBUG
+		printf("ASU3 file could not be opened...\n");
+#endif
+		return 1;
+	}
+
+#else
+	if (td->iocount <= 0) return 1;
+
+	td->iopos = 0;
+	// Find the maximum block size for creating buffers
+	for (i=0; i<td->iocount; i++) {
+		int rw = td->iostore[i].dir;
+		int bytes = BLOCK_TO_B(td->iostore[i].len);
+
+		if (bytes > td->o.max_bs[rw])
+			td->o.max_bs[rw] = bytes;
+	}
+#endif
+
+#ifdef _SPC1_DEBUG
+	printf("Initialisation finished for bsu = %d, str = %d, pid = %d\n", td->bsu, td->str, getpid());
+	fflush(stdout);
+#endif
+
+	return 0;
+}
+
+int fin_spc1_io(struct thread_data *td) {
+	int fileno;
+
+	if ( (td->bsu >= BSU) || (td->str >= STREAMS) ) return 1;
+#ifdef SINGLE
+
+	fileno = get_fileno(td, ASU1);
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("ASU1 file not open when closing...\n");
+#endif
+		return 1;
+	}
+	td_io_close_file(td, td->files[fileno]);
+	fileno = get_fileno(td, ASU2);
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("ASU2 file not open when closing...\n");
+#endif
+		return 1;
+	}
+	td_io_close_file(td, td->files[fileno]);
+	fileno = get_fileno(td, ASU3);
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("ASU3 file not open when closing...\n");
+#endif
+		return 1;
+	}
+	td_io_close_file(td, td->files[fileno]);
+
+#else
+	if (td->iocount <= 0) return 1;
+#endif
+
+#ifdef _SPC1_DEBUG
+	printf("Finalisation finished for bsu = %d, str = %d, pid = %d\n", td->bsu, td->str, getpid());
+	fflush(stdout);
+#endif
+	return 0;
+}
+
+int get_spc1_io(struct thread_data *td, struct io_u *io_u_addr) {
+
+	struct spc1_io_s spc1_io;
+	int i, j, bsu, str, pos, fileno;
+	unsigned long elapsed, whenMillis, least;
+	unsigned short found;
+
+#ifdef _SPC1_DEBUG
+	printf("Reading from SPC-1 IOs, pid = %d\n", getpid());
+	fflush(stdout);
+#endif
+
+#ifdef SINGLE
+	least = TOTAL_RUNTIME_MILLIS;
+	found = 0;
+	for (i=0; i<BSU; i++)
+		if ( (spc1_context_from_bsu(i) >= BEGIN_CONTEXT) &&
+		     (spc1_context_from_bsu(i) <= END_CONTEXT) ) {
+			for (j=0; j<STREAMS; j++) {
+#ifdef _SPC1_DEBUG
+				printf("single_iocount[%d][%d] = %d, single_iopos[%d][%d] = %d\n",
+						i, j, td->single_iocount[i][j],
+						i, j, td->single_iopos[i][j]
+						);
+#endif
+				if (td->single_iopos[i][j] < td->single_iocount[i][j])
+					if (td->single_iostore[i][j][td->single_iopos[i][j]].when / 10 < least) {
+						bsu = i;
+						str = j;
+						pos = td->single_iopos[i][j];
+#ifdef _SPC1_DEBUG
+						printf("Earlier SPC-1 IOs, bsu = %d, str = %d, pos = %d, pid = %d\n", bsu, str, pos, getpid());
+						fflush(stdout);
+#endif
+						least = td->single_iostore[bsu][str][pos].when / 10;
+						found = 1;
+					}
+			}
+		}
+	if (!found) {
+		td->done = 1;
+		return 1;
+	}
+	spc1_io = td->single_iostore[bsu][str][pos];
+
+#else
+	bsu = td->bsu;
+	str = td->str;
+
+	pos = td->iopos;
+
+	if (pos == td->iocount) {
+		printf("IOs exhausted... bsu = %d, str = %d, pid = %d\n", bsu, str, getpid());
+		/* No more IOs from this (bsu, stream) */
+		td->done = 1;
+		return 1;
+	}
+
+#ifdef _SPC1_DEBUG
+	printf("IO # %d from bsu = %d, str = %d, pid = %d\n", pos, bsu, str, getpid());
+#endif
+	fflush(stdout);
+	spc1_io = td->iostore[pos];
+#endif
+
+#ifdef _SPC1_DEBUG
+	spc1_io_debug_info("SPC-1 IOP", &spc1_io);
+	fflush(stdout);
+#endif
+
+	elapsed = mtime_since_genesis();
+	whenMillis = spc1_io.when / 10;
+#ifdef _SPC1_DEBUG
+	printf("SPC-1 IO: elapsed = %ld, when = %ld, pid = %d\n", elapsed, whenMillis, getpid());
+	fflush(stdout);
+#endif
+	if (whenMillis > elapsed) {
+		usec_sleep(td, (whenMillis - elapsed) * 1000);
+	}
+
+#ifdef _SPC1_DEBUG
+	printf("SPC-1 IO: wait over\n");
+	fflush(stdout);
+#endif
+
+	io_u_addr->ddir = spc1_io.dir;
+	io_u_addr->offset = spc1_io.pos;
+//	io_u_addr->offset = BLOCK_TO_B(spc1_io.pos);
+	io_u_addr->buflen = BLOCK_TO_B(spc1_io.len);
+
+#ifdef _SPC1_DEBUG
+	printf("IO # %d from bsu = %d, str = %d, pid = %d, identifying file...\n", pos, bsu, str, getpid());
+	fflush(stdout);
+#endif
+	/* Get file to read from/write to */
+	switch (td->str) {
+	case 0: case 1: case 2: case 3:
+		fileno = get_fileno(td, ASU1);
+		if (fileno == -1) {
+			td->o.nr_files++;
+			fileno = add_file(td, ASU1);
+		}
+		break;
+	case 4: case 5: case 6:
+		fileno = get_fileno(td, ASU2);
+		if (fileno == -1) {
+			td->o.nr_files++;
+			fileno = add_file(td, ASU2);
+		}
+		break;
+	default: /* case 7: */
+		fileno = get_fileno(td, ASU3);
+		if (fileno == -1) {
+			td->o.nr_files++;
+			fileno = add_file(td, ASU3);
+		}
+		break;
+	}
+	if (fileno == -1) {
+#ifdef _SPC1_DEBUG
+		printf("IO file has not been added... bsu = %d, str = %d, pid = %d\n", bsu, str, getpid());
+#endif
+		return 1;
+	}
+
+	io_u_addr->file = td->files[fileno];
+
+#ifndef SINGLE
+
+	if (pos == 0) {
+#ifdef _SPC1_DEBUG
+		printf("IO # %d from bsu = %d, str = %d, pid = %d, opening file # %d...\n", pos, bsu, str, getpid(), fileno);
+#endif
+		if (td_io_open_file(td, io_u_addr->file)) {
+#ifdef _SPC1_DEBUG
+			printf("IO file could not be opened... bsu = %d, str = %d, pid = %d\n", bsu, str, getpid());
+#endif
+			return 1;
+		}
+	}
+
+	if (pos == td->iocount) {
+#ifdef _SPC1_DEBUG
+		printf("IO # %d from bsu = %d, str = %d, pid = %d, closing file # %d...\n", pos, bsu, str, getpid(), fileno);
+#endif
+		td_io_close_file(td, io_u_addr->file);
+	}
+
+#endif
+
+#ifdef _SPC1_DEBUG
+	printf("IO # %d from bsu = %d, str = %d, pid = %d, getting file %d...\n", pos, bsu, str, getpid(), io_u_addr->file);
+	fflush(stdout);
+#endif
+	get_file(io_u_addr->file);
+
+#ifdef _SPC1_DEBUG
+	fio_io_debug_info("SPC-1 io_u", io_u_addr);
+	fflush(stdout);
+#endif
+
+#ifdef SINGLE
+	td->single_iopos[bsu][str]++;
+#else
+	td->iopos++;
+#endif
+
+#ifdef _SPC1_DEBUG
+	printf("Finished reading IO # %d from bsu = %d, str = %d, pid = %d\n", pos, bsu, str, getpid());
+	fflush(stdout);
+#endif
+
+	return 0;
+}
+
+unsigned short spc1_ios_left(struct thread_data *td) {
+	unsigned short left = 0;
+	int i, j;
+
+	for (i=0; i<BSU; i++) 
+		if ( (spc1_context_from_bsu(i) >= BEGIN_CONTEXT) &&
+		     (spc1_context_from_bsu(i) <= END_CONTEXT) ) {
+			for (j=0; j<STREAMS; j++)
+				if (td->single_iopos[i][j] < td->single_iocount[i][j]) {
+					left = 1;
+					break;
+				}
+			if (left) break;
+		}
+
+	return left;
+}
+
+#endif
diff --git a/spc1_wrapper.h b/spc1_wrapper.h
new file mode 100644
index 0000000..9d30dde
--- /dev/null
+++ b/spc1_wrapper.h
@@ -0,0 +1,93 @@
+#ifndef SPC1_WRAPPER_H_
+#define SPC1_WRAPPER_H_
+
+/* Can change these parameters */
+#define SINGLE
+//#define PROCS
+//#define THREADS
+
+#define BSU 198 // # Max working with PROCS = 25, with SINGLE = 400
+#define BEGIN_CONTEXT 0 /* This limits the BSUs to be those running on context = 0 */
+#define END_CONTEXT 0   /* and context = 0 */
+
+//#define BSU 99 // # Max working with PROCS = 25, with SINGLE = 400
+//#define BEGIN_CONTEXT 0 /* This limits the BSUs to be those running on context = 0 */
+//#define END_CONTEXT 0   /* and context = 1 */
+
+#define MIN_IOPS_GENERATED 100
+
+#define RUNTIME_HRS  0
+#define RUNTIME_MINS 30
+#define RUNTIME_SECS 0
+
+#define ASU1 "/dev/mapper/test-asu1"
+#define ASU2 "/dev/mapper/test-asu2"
+#define ASU3 "/dev/mapper/test-asu3"
+
+#define ASU1_SIZE_GB 20
+#define ASU2_SIZE_GB 20
+#define ASU3_SIZE_GB 20
+
+#define BLOCK_SIZE_KB 4
+
+#define PNAME "fio (v1.36)"
+
+#define GIGABYTE 1073741824
+#define MEGABYTE 1048576
+#define KILOBYTE 1024
+
+#define GB_TO_BLOCK( g ) ( (g)*(GIGABYTE/KILOBYTE)*BLOCK_SIZE_KB )
+#define BLOCK_TO_B( b ) ( (b)*BLOCK_SIZE_KB*KILOBYTE )
+
+#define BUFLEN 1000
+
+#define IOPS_INFO 100000
+#define IOPS_ALL  27900000
+
+/* No more changes required below here */
+#define BSU_ID_FOR_SINGLE -1
+#define STR_ID_FOR_SINGLE -1
+
+#define ASU 3
+
+#define STREAMS 8
+
+#define AVG_IOPS 50
+
+#define TOTAL_TIME_SECS( h, m, s ) ( 60*60*(h) + 60*(m) + (s) )
+#define IN_MILLIS( s ) ( 1000*(s) )
+
+#define TOTAL_RUNTIME_SECS TOTAL_TIME_SECS(RUNTIME_HRS, RUNTIME_MINS, RUNTIME_SECS)
+#define TOTAL_RUNTIME_MILLIS IN_MILLIS(TOTAL_RUNTIME_SECS)
+
+#ifndef _SPC1_H
+#define _SPC1_H
+#include "spc1.h"
+#endif
+
+#include "fio.h"
+
+extern short use_spc1;
+
+extern struct spc1_io_s *** iostore;
+
+extern unsigned ** iocount;
+
+extern unsigned spc1_context_from_bsu(unsigned bsu);
+
+extern int gen_spc1_ios();
+
+extern char* gen_spc1_file(char *string, unsigned int *global_addr,
+		unsigned int *line_addr, int *bsu_addr, int *str_addr);
+
+extern int init_spc1_io(struct thread_data *td);
+extern int fin_spc1_io(struct thread_data *td);
+
+extern int get_spc1_io(struct thread_data *td, struct io_u *io_u_addr);
+
+extern void spc1_io_debug_info(const char *pre, struct spc1_io_s *spc1_io_s_addr);
+extern void fio_io_debug_info(const char *pre, struct io_u *io_u_addr);
+
+extern unsigned short spc1_ios_left(struct thread_data *td);
+
+#endif /*SPC1_WRAPPER_H_*/
-- 
1.6.5.1.1367.gcd48


[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux