コード例 #1
0
ファイル: test_1_5.cpp プロジェクト: thuhujin/746
int main(int argc, char *argv[])
{
  int ret_status;
  Address address;
  if(argc != 3) {
    printf("usage: test_1_5 <config_file_name> <log_file_path>\n");
    exit(EXIT_FAILURE);
  }

  strcpy(log_file_path, argv[2]);
  log_file_stream = fopen(log_file_path, "w+");

  load_config(argv[1]);
	
	fprintf(log_file_stream, "------------------------------------------------------------\n");

  Ssd *ssd = new Ssd(log_file_stream);
  print_config(log_file_stream);
	
	fprintf(log_file_stream, "----------------\nReading LBA 0\n");

  ssd -> event_arrive(READ, 0, 1, 1, &ret_status, address);
  if((ret_status == SUCCESS) || (ssd->is_valid(0, address))) {
    fprintf(log_file_stream, "Read on uninitialized LBA 0 succeeded\n");
    failed(ssd);
  }
  fflush(log_file_stream);
  fclose(log_file_stream);
  delete ssd;
  printf("SUCCESS ...Check %s for more details.\n", log_file_path);
  return 0;
}
コード例 #2
0
ファイル: run_ssd_blkdev.cpp プロジェクト: casslab/ssd_blkdev
int main()
{
	load_config();
	print_config(NULL);

	int fd;
	Ssd *ssd = new Ssd();
	double cur_time = 1.0;
	double delta = BUS_DATA_DELAY - 2 > 0 ? BUS_DATA_DELAY - 2 : BUS_DATA_DELAY;
	enum event_type event_type;

	fd = open(SSD_DEV_NODE, O_RDWR);
	if (fd < 0) {
		perror("Failed to open the device node");
		return errno;
	}

	ioctl(fd, SSD_BLKDEV_REGISTER_APP);
	printf("Registered the application with the driver..\n");

	while (1) {
			ioctl(fd, SSD_BLKDEV_GET_LBN, &request_map);
//			printf("[%lu] Request LBA: %lu; Size: %u sectors; Dir: %d\n",
//					++req_cnt, request_map.lba, request_map.num_sectors, request_map.dir);

			event_type = request_map.dir ? WRITE : READ;
			ssd->event_arrive(event_type, request_map.lba, 1, cur_time);

			printf("[%lu]: LBA: %lu; PPN = %lu; Dir: %d\n", ++req_cnt, request_map.lba, request_map.ppn, request_map.dir);

//			request_map.ppn = request_map.lba;
			ioctl(fd, SSD_BLKDEV_SET_PPN, &request_map);

			cur_time += delta;
	}

	close(fd);

	delete ssd;
	return 0;
}
コード例 #3
0
ファイル: run_bimodal.cpp プロジェクト: H-j721/flashsim
int main(int argc, char **argv){

	long vaddr;

	double arrive_time;

	load_config();
	print_config(NULL);

	Ssd ssd;

	printf("INITIALIZING SSD Bimodal\n");

	srandom(1);
	int preIO = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE;

	if (FTL_IMPLEMENTATION == 0) // PAGE
		preIO -= 16*BLOCK_SIZE;

	if (FTL_IMPLEMENTATION == 1) // BAST
		preIO -= (BAST_LOG_PAGE_LIMIT*BLOCK_SIZE)*2;

	if (FTL_IMPLEMENTATION == 2) // FAST
		preIO -= (FAST_LOG_PAGE_LIMIT*BLOCK_SIZE)*1.1;

	if (FTL_IMPLEMENTATION > 2) // DFTL BIFTL
		preIO -= 512;

	int deviceSize = 3145216;

	if (preIO > deviceSize)
		preIO = deviceSize;

	printf("Writes %i pages for startup out of %i total pages.\n", preIO, SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE);

	double start_time = 0;
	double timeMultiplier = 10000;

	double read_time = 0;
	double write_time = 0;
	double trim_time = 0;

	unsigned long num_reads = 0;
	unsigned long num_writes = 0;
	unsigned long num_trims = 0;

	std::vector<double> avgsTrim;
	std::vector<double> avgsWrite1;
	std::vector<double> avgsRead1;
	std::vector<double> avgsRead2;
	std::vector<double> avgsRead3;
	std::vector<double> avgsTrim2;
	std::vector<double> avgsWrite2;
	std::vector<double> avgsRead4;
	std::vector<double> avgsWrite3;


	avgsTrim.reserve(1024*64);
	avgsWrite1.reserve(1024*64);
	avgsRead1.reserve(1024*64);
	avgsRead2.reserve(1024*64);
	avgsRead3.reserve(1024*64);
	avgsTrim2.reserve(1024*64);
	avgsWrite2.reserve(1024*64);
	avgsRead4.reserve(1024*64);
	avgsWrite3.reserve(1024*64);

	// Reset statistics
	ssd.reset_statistics();

	// 1. Write random to the size of the device
	srand(1);
	double afterFormatStartTime = 0;
	//for (int i=0; i<preIO/3*2;i++)
	for (int i=0; i<preIO*1.1;i++)
	//for (int i=0; i<700000;i++)
	{
		long int r = random()%preIO;
		double d = ssd.event_arrive(WRITE, r, 1, afterFormatStartTime);
		afterFormatStartTime += d;

		if (i % 10000 == 0)
			printf("Wrote %i %f\n", i,d );
	}

	start_time = afterFormatStartTime;
	// Reset statistics
	ssd.reset_statistics();

	// 2. Trim an area. ( We let in be 512MB (offset 131072 pages or 2048 blocks) into the address space, and then 256MB (1024 blocks or 65536 pages) )

	int startTrim = 2048*64; //131072
	int endTrim = 3072*64; //196608

	/* Test 1 */
	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(TRIM, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsTrim.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Trim: %i %f\n", i, trim_time);

	}

	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsRead1.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Read: %i %f\n", i, trim_time);

	}

	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsRead2.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Read: %i %f\n", i, trim_time);

	}

	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(WRITE, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsWrite1.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Write: %i %f\n", i, trim_time);

	}

	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsRead3.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Read: %i %f\n", i, trim_time);

	}

	/* Test 1 */
	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(TRIM, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsTrim2.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (trim_time > 400)
			printf("Trim: %i %f\n", i, trim_time);

	}

	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(WRITE, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsWrite2.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Write: %i %f\n", i, trim_time);

	}

	for (int i=startTrim; i<endTrim;i++)
	{

		trim_time = ssd.event_arrive(READ, i, 1, ((start_time+arrive_time)*timeMultiplier));
		avgsRead4.push_back(trim_time);
		num_trims++;

		arrive_time += trim_time;

		if (i % 1000 == 0)
			printf("Read: %i %f\n", i, trim_time);

	}

//	// 1. Write random to the size of the device
//	for (int i=0; i<700000;i++)
//	{
//		long int r = (random()%preIO-200000)+200000;
//		double d = ssd.event_arrive(WRITE, r, 1, afterFormatStartTime);
//		afterFormatStartTime += d;
//
//		if (i % 10000 == 0)
//			printf("Wrote %i %f\n", i,d );
//	}
//
//	for (int i=startTrim; i<endTrim;i++)
//	{
//
//		trim_time = ssd.event_arrive(WRITE, i, 1, ((start_time+arrive_time)*timeMultiplier));
//		avgsWrite3.push_back(trim_time);
//		num_trims++;
//
//		arrive_time += trim_time;
//
//		if (i % 1000 == 0)
//			printf("Write: %i %f\n", i, trim_time);
//
//	}


	ssd.print_ftl_statistics();

	FILE *logFile = NULL;
	if ((logFile = fopen("output.log", "w")) == NULL)
	{
		printf("Output file cannot be written to.\n");
		exit(-1);
	}

	fprintf(logFile, "Trim;Read1;Read2;Write1;Read3;Trim2;Write2;Read4;Write3\n");

	for (size_t i=0;i<avgsTrim.size();i++)
	{
		fprintf(logFile, "%f;%f;%f;%f;%f;%f;%f;%f\n", avgsTrim[i],avgsRead1[i], avgsRead2[i], avgsWrite1[i], avgsRead3[i], avgsTrim2[i], avgsWrite2[i], avgsRead4[i]);
	}

	fclose(logFile);

	ssd.print_ftl_statistics();
	ssd.print_statistics();

	printf("Finished.\n");
	return 0;
}
コード例 #4
0
ファイル: run_ufliptrace.cpp プロジェクト: arh/sim-ideal
int main(int argc, char **argv){

	long vaddr;
	ssd::uint queryTime;
	char ioPatternType; // (S)equential or (R)andom
	char ioType; // (R)ead or (W)rite
	double arrive_time;
	int ioSize;

	char line[80];

	double afterFormatStartTime = 0;

	load_config();
	print_config(NULL);

	Ssd ssd;

	printf("INITIALIZING SSD\n");
	
	unsigned long long deviceSize = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE ;

	//ARH: I don't understand what is the point of warm-up phase here.
	/*
	int preIO = SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE;

	if (FTL_IMPLEMENTATION == 0) // PAGE
		preIO -= 16*BLOCK_SIZE;

	if (FTL_IMPLEMENTATION == 1) // BAST
		preIO -= (BAST_LOG_PAGE_LIMIT*BLOCK_SIZE)*1.2;

	if (FTL_IMPLEMENTATION == 2) // FAST
		preIO -= (FAST_LOG_PAGE_LIMIT*BLOCK_SIZE)*1.1;

	if (FTL_IMPLEMENTATION > 2) // DFTL BIFTL
		preIO -= 1000;

	//int deviceSize = 2827059;
	int deviceSize = 2097024;

	if (preIO > deviceSize)
		preIO = deviceSize;

	printf("Writes %i pages for startup out of %i total pages.\n", preIO, SSD_SIZE * PACKAGE_SIZE * DIE_SIZE * PLANE_SIZE * BLOCK_SIZE);

//	srand(1);
//	for (int i=0; i<preIO*3;i++)
//	{
//		long int r = random()%deviceSize;
//		double d = ssd.event_arrive(WRITE, r, 1, (double)i*1000.0);
//		//double d = ssd.event_arrive(WRITE, i, 1, i*1000);
//		afterFormatStartTime += 1000;
//
//		if (i % 1000 == 0)
//			printf("Wrote %i %f\n", i,d );
//	}
	*/

	DIR *working_directory = NULL;
	if ((working_directory = opendir(argv[1])) == NULL)
	{
		printf("Please provide trace file directory.\n");
		exit(-1);
	}

	std::vector<std::string> files;
	struct dirent *dirp;
	while ((dirp = readdir(working_directory)) != NULL)
	{
		if (dirp->d_type == DT_REG)
			files.push_back(dirp->d_name);
	}

	std::sort(files.begin(), files.end());

	double start_time = afterFormatStartTime;
	double timeMultiplier = 10000;


	long writeEvent = 0;
	long readEvent = 0;
	/* No pre-write
	for (unsigned int i=0; i<files.size();i++)
	{
		char *filename = NULL;
		asprintf(&filename, "%s%s", argv[1], files[i].c_str());

		FILE *trace = NULL;
		if((trace = fopen(filename, "r")) == NULL){
			printf("File was moved or access was denied.\n");
			exit(-1);
		}

		printf("-__- %s -__-\n", files[i].c_str());

		start_time = start_time + arrive_time;


		int addressDivisor = 1;
		float multiplier = 1;

		std::string fileName = files[i].c_str();
		std::string multiplerStr = fileName.substr(fileName.find('P',0)+1, fileName.find_last_of('_', std::string::npos)-fileName.find('P',0)-1);

		char pattern = fileName.substr(4,1).c_str()[0];
		switch (pattern)
		{
		case '5':
			multiplier = atof(multiplerStr.c_str());
			break;

		}
		
		//ARH: access one page per iteration
		// first go through and write to all read addresses to prepare the SSD 
		while(fgets(line, 80, trace) != NULL){
			sscanf(line, "%c; %c; %li; %u; %i; %lf", &ioPatternType, &ioType, &vaddr, &queryTime, &ioSize, &arrive_time);


			double local_loop_time = 0;

			if (ioType == 'R')
			{
				for (int i=0;i<ioSize;i++)
				{
					local_loop_time += ssd.event_arrive(READ, ((vaddr+(i*(int)multiplier))/addressDivisor)%deviceSize, 1, ((start_time+arrive_time)*timeMultiplier)+local_loop_time);
					readEvent++;
				}


			}
			else if(ioType == 'W')
			{
				for (int i=0;i<ioSize;i++)
				{
					local_loop_time += ssd.event_arrive(WRITE, ((vaddr+(i*(int)multiplier))/addressDivisor)%deviceSize, 1, ((start_time+arrive_time)*timeMultiplier)+local_loop_time);
					writeEvent++;
				}


			}

			arrive_time += local_loop_time;
		}

		fclose(trace);
	}

	printf("Pre write done------------------------------\n");
	ssd.print_ftl_statistics();
	printf("Num read %li write %li\n", readEvent, writeEvent);
	getchar();
	
	*/
		
	FILE *logFile = NULL;
	if ((logFile = fopen("output.csv", "w")) == NULL)
	{
		printf("Output file cannot be written to.\n");
		exit(-1);
	}

	fprintf(logFile, "File;NumIOReads;ReadIOTime;NumIOWrites;WriteIOTime;NumIOTotal;IOTime;");
	ssd.write_header(logFile);

	double read_time = 0;
	double write_time = 0;

	unsigned long num_reads = 0;
	unsigned long num_writes = 0;

	for (unsigned int i=0; i<files.size();i++)
	{
		char *filename = NULL;
		asprintf(&filename, "%s%s", argv[1], files[i].c_str());
		
		FILE *trace = NULL;
		if((trace = fopen(filename, "r")) == NULL){
			printf("File was moved or access was denied.\n");
			exit(-1);
		}

		fprintf(logFile, "%s;", files[i].c_str());

		printf("-__- %s -__-\n", files[i].c_str());

		start_time = start_time + arrive_time;

		// Reset statistics
		ssd.reset_statistics();

		num_reads = 0;
		read_time = 0;

		num_writes = 0;
		write_time = 0;

		int addressDivisor = 1;
		float multiplier = 1;

		std::string fileName = files[i].c_str();
		std::string multiplerStr = fileName.substr(fileName.find('P',0)+1, fileName.find_last_of('_', std::string::npos)-fileName.find('P',0)-1);


		/* first go through and write to all read addresses to prepare the SSD */
		while(fgets(line, 80, trace) != NULL){
			sscanf(line, "%c; %c; %li; %u; %i; %lf", &ioPatternType, &ioType, &vaddr, &queryTime, &ioSize, &arrive_time);

			//printf("%li %c %c %li %u %lf %lf %li\n", ++cnt, ioPatternType, ioType, vaddr, queryTime, arrive_time, start_time+arrive_time);

			double local_loop_time = 0;

			if (ioType == 'R')
			{
				for (int i=0;i<ioSize;i++)
				{
					local_loop_time += ssd.event_arrive(READ, ((vaddr+(i*(int)multiplier))/addressDivisor)%deviceSize, 1, ((start_time+arrive_time)*timeMultiplier)+local_loop_time);
				}
				num_reads++;

				read_time += local_loop_time;
			}
			else if(ioType == 'W')
			{
				for (int i=0;i<ioSize;i++)
				{
					local_loop_time += ssd.event_arrive(WRITE, ((vaddr+(i*(int)multiplier))/addressDivisor)%deviceSize, 1, ((start_time+arrive_time)*timeMultiplier)+local_loop_time);

				}
				num_writes++;
				write_time += local_loop_time;

			}

			arrive_time += local_loop_time;
		}
		// Write all statistics
		fprintf(logFile, "%lu;%f;%lu;%f;%lu;%f;", num_reads, read_time, num_writes, write_time, num_reads+num_writes, read_time+write_time);
		ssd.write_statistics(logFile);
		fclose(trace);
		fflush(logFile);
	}

	fclose(logFile);

	closedir(working_directory);

	printf("Finished.\n");
	return 0;
}
コード例 #5
0
ファイル: run_correctness.cpp プロジェクト: H-j721/flashsim
int main(int argc, char** argv)
{
	load_config();
	print_config(NULL);
	printf("\n");

	Ssd *ssd = new Ssd();

	// create memory mapping of file that we are going to check with
	int fd;
	if (argc == 1)
		fd = open_temp_file();
	else
		fd = open(argv[1], O_RDONLY);
	struct stat st;
	fstat(fd, &st);

	void *test_data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

	if (test_data == MAP_FAILED)
		fprintf(stderr, "File not mapped.");

	printf("Size of testfile: %iKB\n", (int)st.st_size/1024);

	/*
	 * Experiment setup
	 * 1. Do linear write and read.
	 * 2. Write linear again and  read.
	 * 2. Do semi-random linear
	 * 3. Do random
	 * 4. Do backward linear
	 */

	double result = 0;

	printf("Test 1. Write sequential test data.\n");
	result += do_seq(ssd, WRITE, test_data, st.st_size);

	printf("Test 1. Write sequential test data.\n");
	result += do_seq(ssd, WRITE, test_data, st.st_size);

	printf("Test 1. Write sequential test data.\n");
	result += do_seq(ssd, WRITE, test_data, st.st_size);
//
//	printf("Test 1. Trim data.\n");
//	result += do_seq(ssd, TRIM, test_data, st.st_size);

	printf("Test 1. Write sequential test data.\n");
		result += do_seq(ssd, WRITE, test_data, st.st_size);

	printf("Test 2. Read sequential test data.\n");
	result += do_seq(ssd, READ, test_data, st.st_size);

//	printf("Test 6. Write backward sequential test data.\n");
//	result += do_seq_backward(ssd, WRITE, test_data, st.st_size);
//
//	printf("Test 9. Read backward sequential test data.\n");
//	result += do_seq_backward(ssd, READ, test_data, st.st_size);

//	printf("Test 3. Write second write.\n");
//	result += do_seq(ssd, WRITE, test_data, st.st_size);
//
//	printf("Test 4. Write third write.\n");
//	result += do_seq_backward(ssd, WRITE, test_data, st.st_size);
//
//	printf("Test 5. Read sequential test data.\n");
//	result += do_seq_backward(ssd, READ, test_data, st.st_size);
//
//	printf("Test 6. Write backward sequential test data.\n");
//	result += do_seq_backward(ssd, WRITE, test_data, st.st_size);
//
//	printf("Test 7. Read backward sequential test data.\n");
//	result += do_seq_backward(ssd, READ, test_data, st.st_size);
//
//	printf("Test 8. Write backward sequential test data again.\n");
//	result += do_seq_backward(ssd, WRITE, test_data, st.st_size);
//
//	printf("Test 9. Read backward sequential test data.\n");
//	result += do_seq_backward(ssd, READ, test_data, st.st_size);

	printf("Write time: %.10lfs\n", result);

	ssd->print_statistics();
	delete ssd;
	return 0;
}
コード例 #6
0
ファイル: run_trace.cpp プロジェクト: thuhujin/746
int main(int argc, char **argv){
	double arrive_time;
	unsigned int diskno;
	unsigned long vaddr;
	unsigned int size;
	unsigned int op;
	char line[80];
	double read_time = 0;
	double write_time = 0;
	double read_total = 0;
	double write_total = 0;
	unsigned long num_reads = 0;
	unsigned long num_writes = 0;

  if(argc != 3) {
    printf("usage: run_trace <trace_file> <config_file>\n");
    exit(0);
  }
	load_config(argv[2]);
	print_config(NULL);
	printf("Press ENTER to continue...");
	getchar();
	printf("\n");

	Ssd ssd;

	FILE *trace = NULL;
	if((trace = fopen(argv[1], "r")) == NULL){
		printf("Please provide trace file name\n");
		exit(-1);
	}

	printf("INITIALIZING SSD\n");

	/* first go through and write to all read addresses to prepare the SSD */
	while(fgets(line, 80, trace) != NULL){
		sscanf(line, "%lf %u %lu %u %u", &arrive_time, &diskno, &vaddr, &size, &op);
		vaddr %= 65536;
		if(op == 1)
			(void) ssd.event_arrive(WRITE, vaddr, size, arrive_time);
	}

	printf("STARTING TRACE\n");

	/* now rewind file and run trace */
	fseek(trace, 0, SEEK_SET);
	while(fgets(line, 80, trace) != NULL){
		sscanf(line, "%lf %u %lu %u %u", &arrive_time, &diskno, &vaddr, &size, &op);
		vaddr %= 65536;
		if(op == 0){
			write_time = ssd.event_arrive(WRITE, vaddr, size, arrive_time);
			if(write_time != 0){
				write_total += write_time;
				num_writes++;
			}
		} else if(op == 1){
			read_time = ssd.event_arrive(READ, vaddr, size, arrive_time);
			if(read_time != 0){
				read_total += read_time;
				num_reads++;
			}
		} else
			fprintf(stderr, "Bad operation in trace\n");
	}
	printf("Num reads : %lu\n", num_reads);
	printf("Num writes: %lu\n", num_reads);
	printf("Avg read time : %.20lf\n", read_time / num_reads);
	printf("Avg write time: %.20lf\n", write_time / num_writes);
	return 0;
}
コード例 #7
0
ファイル: run_test_closed.cpp プロジェクト: at-k/flashsim
int main(int argc, char **argv)
{
	char read_file_name[100] = "";
	char write_file_name[100] = "";
	std::set<unsigned int> addresses;
	FILE *read_file;
	FILE *write_file;
	double initial_delay;
	unsigned int q_depth;
	bool write_data;
	//unsigned int req_per_thread = 1000;
	
	unsigned int total_read_count = 10000000, cur_read_count = 0;


	load_config();
	print_config(NULL);
	printf("\n");

	Ssd *ssd = new Ssd();
	srand(10111);

	unsigned int write = atoi(argv[1]);
	unsigned int util_percent = atoi(argv[2]);
	q_depth = atoi(argv[3]);
	//total_read_count = q_depth * 10000;

	char ftl_implementation[10] = {'0' + FTL_IMPLEMENTATION};
	char gc_scheme[10] = {'0' + GC_SCHEME};


	printf("addressable blocks %d\n", NUMBER_OF_ADDRESSABLE_BLOCKS);
	unsigned int lastLBA = NUMBER_OF_ADDRESSABLE_BLOCKS * BLOCK_SIZE;


	strcat(read_file_name, "closed_read_");
	strcat(read_file_name, ftl_implementation);
	strcat(read_file_name, "_");
	strcat(read_file_name, gc_scheme);
	strcat(read_file_name, "_");
	strcat(read_file_name, argv[1]);
	strcat(read_file_name, "_");
	strcat(read_file_name, argv[2]);
	strcat(read_file_name, "_");
	strcat(read_file_name, argv[3]);
	strcat(read_file_name, ".out");

	strcat(write_file_name, "closed_write_");
	strcat(write_file_name, ftl_implementation);
	strcat(write_file_name, "_");
	strcat(write_file_name, gc_scheme);
	strcat(write_file_name, "_");
	strcat(write_file_name, argv[1]);
	strcat(write_file_name, "_");
	strcat(write_file_name, argv[2]);
	strcat(write_file_name, "_");
	strcat(write_file_name, argv[3]);
	strcat(write_file_name, ".out");


	read_file = fopen(read_file_name, "w");
	write_file = fopen(write_file_name, "w");

	bool noop_complete = false;
	double next_noop_time = 0;
	double prev_noop_time = 0;

	bool write_complete = false;
	double write_end_time = 0;

	unsigned int occupied = util_percent*lastLBA/100;
	unsigned int i=0;
	for (i = 0; i < occupied; i++)
	{
		write_complete = false;
		bool result = ssd -> event_arrive(WRITE, i%lastLBA, 1, write_end_time, write_complete, write_end_time);
		if(result == false)
		{
			printf("returning failure\n");
			return -1;
		}
		//printf("Write %d %f\n", write_complete, write_end_time);
		prev_noop_time = write_end_time;
		int k = 0;
		while(!write_complete)
		{
			ssd->event_arrive(NOOP, 1, 1, prev_noop_time, noop_complete, next_noop_time);
			prev_noop_time = next_noop_time;
			k++;
		}
		addresses.insert(i);
	}
	initial_delay = write_end_time;
	printf("Completed\n");
	fflush(stdout);
	if(write == 0)
	{
		write_data = false;
	}
	else
	{
		write_data = true;
		q_depth = 2*q_depth;
	}

	printf("starting experiment\n");
	fflush(stdout);
	unsigned int count[q_depth];
	bool op_complete[q_depth];
	double op_start_time[q_depth];
	double op_complete_time[q_depth];
	unsigned int op_addresses[q_depth];
	for (unsigned int i=0;i<q_depth;i++)
	{
		count[i] = 0;
		op_complete[i] = false;
		op_start_time[i] = initial_delay;
		op_addresses[i] = 0;
	}	
	next_noop_time = initial_delay;
	unsigned int location = 0;
	unsigned int write_count = 0;
	bool loop = true;
	for(unsigned int i=0;i<q_depth;i++)
	{
		bool result;
		if(write_data && i >= q_depth/2)
		{
			location = rand()%lastLBA;
			result = ssd->event_arrive(WRITE, location, 1, (double) op_start_time[i], op_complete[i], op_complete_time[i]);
			if(result == false)
			{
				fprintf(read_file, "==========\nCould not do a write, incomplete experiment\n");
				goto exit;
			}
			op_addresses[i] = location;
		}	
		else
		{
			
			location = rand()%lastLBA;
			while(addresses.find(location) == addresses.end())
			{
				location = rand()%lastLBA;
			}
			
			result = ssd->event_arrive(READ, location, 1, (double) op_start_time[i], op_complete[i], op_complete_time[i]);
			if(result == -1)
			{
				fprintf(read_file, "==========\nCould not do a read, incomplete experiment\n");
				goto exit;
			}
		}
	}
	
	prev_noop_time = initial_delay;
	while(loop)
	{
		bool event_completed = false;
		unsigned int loop_c = 0;
		double earliest_event = -1;
		unsigned int earliest_event_index = 0;
		for(unsigned int i=0;i<q_depth;i++)
		{
			//printf("%d %p %d %f %f\n", i, &op_complete[i], op_complete[i], op_complete_time[i], earliest_event);
			if(op_complete[i])
			{
				event_completed = true;
				if(op_complete_time[i] < earliest_event || earliest_event == -1)
				{
					earliest_event = op_complete_time[i];
					earliest_event_index = i;
				}
			}
		}
		if(event_completed)
			prev_noop_time = earliest_event < prev_noop_time ? earliest_event : prev_noop_time;
		while(!event_completed)
		{
			ssd->event_arrive(NOOP, 1, 1, prev_noop_time, noop_complete, next_noop_time);
			prev_noop_time = next_noop_time;
			for(unsigned int i=0;i<q_depth;i++)
			{
				printf("%d %d %f %f\n", i, op_complete[i], op_complete_time[i], earliest_event);
				if(op_complete[i])
				{
					event_completed = true;
					if(op_complete_time[i] < earliest_event || earliest_event == -1)
					{
						earliest_event = op_complete_time[i];
						earliest_event_index = i;
					}
				}
			}
			if(event_completed)
				prev_noop_time = earliest_event < prev_noop_time ? earliest_event : prev_noop_time;
			else
				prev_noop_time = next_noop_time;
			loop_c++;
		}
		//for(unsigned int i=0;i<q_depth;i++)
		//{
			//printf("op complete %d %d\n", i, op_complete[i]);
			//if(op_complete[i])
			//{
				bool result = false;
				op_complete[earliest_event_index] = false;
				//printf("Earliest event index %d earliest event time %f\n", earliest_event_index, earliest_event);
				if(write_data && earliest_event_index >= q_depth/2)
				{
					count[earliest_event_index]++;
					addresses.insert(op_addresses[earliest_event_index]);
					fprintf(write_file, "%.5lf\t%.5lf\t%.5lf\n", op_start_time[earliest_event_index], op_complete_time[earliest_event_index] - op_start_time[earliest_event_index], op_complete_time[earliest_event_index]);
					write_count++;
					op_start_time[earliest_event_index] = op_complete_time[earliest_event_index];
					location = rand()%lastLBA;
					op_addresses[earliest_event_index] = location;
					result = ssd->event_arrive(WRITE, location, 1, (double) op_start_time[earliest_event_index], op_complete[earliest_event_index], op_complete_time[earliest_event_index]);
					if(result == false)
					{
						fprintf(read_file, "==========\nCould not do a write, incomplete experiment\n");
						goto exit;
					}
				}	
				else
				{
					fprintf(read_file, "%.5lf\t%.5lf\t%.5lf\n", op_start_time[earliest_event_index], op_complete_time[earliest_event_index] - op_start_time[earliest_event_index], op_complete_time[earliest_event_index]);
					count[earliest_event_index]++;
					op_start_time[earliest_event_index] = op_complete_time[earliest_event_index];
					location = rand()%lastLBA;
					while(addresses.find(location) == addresses.end())
					{
						location = rand()%lastLBA;
					}
					cur_read_count++;	
					op_addresses[earliest_event_index] = location;
					result = ssd->event_arrive(READ, location, 1, (double) op_start_time[earliest_event_index], op_complete[earliest_event_index], op_complete_time[earliest_event_index]);
					if(result == false)	
					{
						fprintf(read_file, "==========\nCould not do a read, incomplete experiment\n");
						goto exit;
					}
				}
				//prev_noop_time = op_complete_time[i] < prev_noop_time ? op_complete_time[i] : prev_noop_time;
			//}
		//}
		
		if(cur_read_count >= total_read_count)
		{
			loop = false;
			break;
		}
		
	}
exit:
	fprintf(stdout, "========================\n");
	fprintf(stdout, "experiment ended with write_count as %d\n", write_count);
	ssd->print_ftl_statistics(stdout);
	fclose(read_file);
	fclose(write_file);
	delete ssd;
	return 0;
}