Exemple #1
0
void
test_using(const char *ctl, char *buf, int bytes, void (*copyf)(const void *s1, void *d, size_t bytes))
{
    int i;
    int loops;
    long long us;

    start_timing();
    for (i = 0; (i & 31) || stop_timing(0, NULL) == 0; ++i) {
	copyf(buf, buf + bytes, bytes);
    }

    loops = i * 2;
    start_timing();
    for (i = loops - 1; i >= 0; --i) {
	copyf(buf, buf + bytes, bytes);
    }
#if 0
    fpcleanup();
#endif
    stop_timing(loops, ctl);
    us = get_timing();
    printf("%s %d %5.2f MBytes/sec\n", ctl, bytes, 
	(double)loops * (double)bytes / (double)us);
}
Exemple #2
0
/* Determines the overhead of tsc timing.  Note the start/stop calls are
 * inlined, so we're trying to determine the lowest amount of overhead
 * attainable by using the TSC (or whatever timing source).
 *
 * For more detailed TSC measurements, use test_rdtsc() in k/a/i/rdtsc_test.c */
void train_timing() 
{
	uint64_t min_overhead = UINT64_MAX;
	uint64_t max_overhead = 0;
	uint64_t time, diff;
	int8_t irq_state = 0;

	/* Reset this, in case we run it again.  The use of start/stop to determine
	 * the overhead relies on timing_overhead being 0. */
	system_timing.timing_overhead = 0;
	/* timing might use cpuid, in which case we warm it up to avoid some extra
	 * variance */
	time = start_timing();
 	diff = stop_timing(time);
	time = start_timing();
 	diff = stop_timing(time);
	time = start_timing();
 	diff = stop_timing(time);
	disable_irqsave(&irq_state);
	for (int i = 0; i < 10000; i++) {
		time = start_timing();
 		diff = stop_timing(time);
		min_overhead = MIN(min_overhead, diff);
		max_overhead = MAX(max_overhead, diff);
	}
	enable_irqsave(&irq_state);
	system_timing.timing_overhead = min_overhead;
	printk("TSC overhead (Min: %llu, Max: %llu)\n", min_overhead, max_overhead);
}
Exemple #3
0
int
main(int ac, char **av)
{
	long long count = 0;
	long long max;
	char c;
	int j;

	printf("timing standard getuid() syscall, single thread\n");
	printf("if using powerd, run several times\n");

	start_timing();
	while (stop_timing(0, NULL) == 0) {
		for (j = 0; j < 100; ++j)
			getuid();
		count += 100;
	}
	max = count;
	start_timing();
	for (count = 0; count < max; count += 100) {
		for (j = 0; j < 100; ++j)
			getuid();
	}
	stop_timing(count, "getuid()");
	return(0);
}
Exemple #4
0
int
main(int ac, char **av)
{
    long long count = 0;
    long long max;
    int j;
    struct timeval tv;

    printf("timing standard gettimeofday() syscall\n");

    start_timing();
    while (stop_timing(0, NULL) == 0) {
	for (j = 0; j < 100; ++j)
	    gettimeofday(&tv, NULL);
	count += 100;
    }
    max = count;
    start_timing();
    for (count = 0; count < max; count += 100) {
	for (j = 0; j < 100; ++j)
	    gettimeofday(&tv, NULL);
    }
    stop_timing(count, "gettimeofday()");
    return(0);
}
Exemple #5
0
int
main(int ac, char **av)
{
    long long count = 0;
    long long max;
    struct timespec ts;
    int j;

    printf("timing standard clock_gettime() syscall\n");

    start_timing();
    while (stop_timing(0, NULL) == 0) {
	for (j = 0; j < 100; ++j)
	    clock_gettime(CLOCK_REALTIME_FAST, &ts);
	count += 100;
    }
    max = count;
    start_timing();
    for (count = 0; count < max; count += 100) {
	for (j = 0; j < 100; ++j)
	    clock_gettime(CLOCK_REALTIME_FAST, &ts);
    }
    stop_timing(count, "getuid()");
    return(0);
}
Exemple #6
0
int
main(int ac, char **av)
{
    long long count = 0;
    long long max;
    int j;
    int *counter;
    pid_t pid;

    printf("Test simple locked bus cycle mutex latency\n");
    printf("auto-forks two processes for the test with shared memory\n");
    printf("This test is only useful on a SMP box\n");

    start_timing();
    mtx = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
    counter = mtx + 64;
    while (stop_timing(0, NULL) == 0) {
	for (j = 0; j < 100; ++j) {
	    get_mtx(1);
	    rel_mtx();
	}
	count += 100;
    }
    max = count;
    *mtx = 0;

    start_timing();
    for (count = 0; count < max; count += 100) {
	for (j = 0; j < 100; ++j) {
	    get_mtx(1);
	    rel_mtx();	/* release */
	    ++counter[64];
	}
    }
    stop_timing(count, "complex_mtx(uncontested/1cpu)");

    if ((pid = fork()) == 0) {
	for (;;) {
	    for (j = 0; j < 100; ++j) {
		get_mtx(2);
		rel_mtx();	/* release */
		++counter[128];
	    }
	}
    } else {
	start_timing();
	for (count = 0; count < max; count += 100) {
	    for (j = 0; j < 100; ++j) {
		get_mtx(1);
		rel_mtx();	/* release */
		++counter[64];
	    }
	}
	stop_timing(count, "complex_mtx");
	printf("proc1=%d proc2=%d\n", counter[64], counter[128]);
	kill(pid, 9);
    }
    return(0);
}
Exemple #7
0
int
main(int ac, char **av)
{
    long long count = 0;
    long long max;
    char c[1];
    int j;
    int loops;
    int fds[2];

    printf("tests full duplex pipe 1write,2read,2write,1read loop\n");
    if (pipe(fds)) {
	perror("pipe");
	exit(1);
    }
    if (fork() == 0) {
	/*
	 * child process
	 */
	close(fds[0]);
	while (read(fds[1], c, sizeof(c)) == sizeof(c)) {
	    write(fds[1], c, sizeof(c));
	}
	_exit(0);
    } else {
	/* 
	 * parent process.
	 */
	close(fds[1]);
	write(fds[0], c, sizeof(c));	/* prime the caches */
	read(fds[0], c, sizeof(c));

	start_timing();
	for (j = 0; ; ++j) {
	    write(fds[0], c, sizeof(c));
	    if (read(fds[0], c, sizeof(c)) != sizeof(c)) {
		fprintf(stderr, "broken pipe during test\n");
		exit(1);
	    }
	   if ((j & 31) == 0 && stop_timing(0, NULL))
		break;
	}
	loops = j;

	start_timing();
	for (j = 0; j < loops; ++j) {
	    write(fds[0], c, sizeof(c));
	    if (read(fds[0], c, sizeof(c)) != sizeof(c)) {
		fprintf(stderr, "broken pipe during test\n");
		exit(1);
	    }
	}
	stop_timing(j, "full duplex pipe / 1char:");
	close(fds[0]);
	while(wait(NULL) >= 0);
    }
    return(0);
}
Exemple #8
0
int
main(int ac, char **av)
{
	long long count = 0;
	long long max;
	char c;
	int n;
	int i;
	int j;
	int fd;
	int status;
	char *path;
	char buf[256];
	struct stat st;

	printf("timing standard fstat() syscall\n");

	fd = open("/tmp/lockmgr3.test", O_RDWR|O_CREAT, 0666);
	assert(fd >= 0);
	start_timing();
	while (stop_timing(0, NULL) == 0) {
		fstat(fd, &st);
		fstat(fd, &st);
		fstat(fd, &st);
		fstat(fd, &st);
		++count;
	}
	max = count * 4;
	close(fd);

	if (ac > 1)
		n = strtol(av[1], NULL, 0);
	else
		n = 1;

	start_timing();
	for (i = 0; i < n; ++i) {
		if (fork() == 0) {
			asprintf(&path, "/tmp/lockmgr.test");
			fd = open(path, O_RDWR|O_CREAT, 0666);
			assert(fd >= 0);
			for (count = 0; count < max; ++count) {
				fstat(fd, &st);
				fstat(fd, &st);
				fstat(fd, &st);
				fstat(fd, &st);
			}
			_exit(0);
		}
	}
	while (wait3(&status, 0, NULL) >= 0 || errno == EINTR)
		;
	stop_timing(max * n * 4, "lockmgr3");

	return(0);
}
void rgb_timing(Test **test, Rgb_Timing *timing)
{

 double total_time,avg_time;
 int i,j;
 unsigned int *rand_uint;

 MYDEBUG(D_RGB_TIMING){
   printf("# Entering rgb_timing(): ps = %u  ts = %u\n",test[0]->psamples,test[0]->tsamples);
 }

 seed = random_seed();
 gsl_rng_set(rng,seed);

 rand_uint = (uint *)malloc((size_t)test[0]->tsamples*sizeof(uint));

 total_time = 0.0;
 for(i=0;i<test[0]->psamples;i++){
   start_timing();
   for(j=0;j<test[0]->tsamples;j++){
     rand_uint[j] = gsl_rng_get(rng);
   }
   stop_timing();
   total_time += delta_timing();
 }
 avg_time = total_time/(test[0]->psamples*test[0]->tsamples);

 timing->avg_time_nsec = avg_time*1.0e+9;
 timing->rands_per_sec = 1.0/avg_time;

 free(rand_uint);
 
}
void dijkstra_pq_threaded(CSRGraph *g, int numThreads)
{
    int *dist = new int[g->size];
    std::mutex *dist_locks = new std::mutex[g->size];
    int i;

    for(i=0;i<g->size;i++)
    {
        dist[i] = MAX_INT;
    }

    int source = 0;
    dist[source] = 0;

    std::priority_queue<Priority_struct, std::vector<Priority_struct>, Compare_priority> pq;
    Priority_struct temp;
    temp.node_name=source;
    temp.node_weight=0;
    pq.push(temp);

    printf("Pushed Initial\n");
    for(int i=0; i< pq.size();i++){
	printf(" %d", pq[i]);
    }
    printf("\n");

    flush_cache();
    start_timing();

    // make threads
    std::vector<std::thread> threads;
    for(i = 0; i < numThreads; ++i){
        threads.push_back(std::thread(dijkstra_pq_thread, g, dist, std::ref(pq), i, dist_locks));
    }

    for (auto it = threads.begin(); it != threads.end(); ++it) {
        std::thread &t = *it;
        t.join();
    }

    stop_timing();

#ifdef PRINT_DISTANCES
    i=0;
    while(i < g->size && i < 10)
    {
        printf("%d ", dist[i]);
        i++;
    }
    printf("\n");
#endif

    delete(dist);
    delete(dist_locks);
    dist = NULL;

}
Exemple #11
0
int
main(int ac, char **av)
{
	long long count = 0;
	long long max;
	char c;
	int n;
	int i;
	int j;
	int status;

	printf("timing standard getuid() syscall, single thread\n");
	printf("if using powerd, run several times\n");

	start_timing();
	while (stop_timing(0, NULL) == 0) {
		for (j = 0; j < 100; ++j)
			getuid();
		count += 100;
	}
	max = count;

	if (ac > 1)
		n = strtol(av[1], NULL, 0);
	else
		n = 1;

	start_timing();
	for (i = 0; i < n; ++i) {
		if (fork() == 0) {
			for (count = 0; count < max; count += 100) {
				for (j = 0; j < 100; ++j)
					getuid();
			}
			_exit(0);
		}
	}
	while (wait3(&status, 0, NULL) >= 0 || errno == EINTR)
		;
	stop_timing(count * n, "getuid()");

	return(0);
}
void dijkstra_LIFO_threaded(CSRGraph *g, int numThreads)
{
    int *dist = new int[g->size];
    std::mutex *dist_locks = new std::mutex[g->size];
    int *onstack = new int[g->size];
    int i;

    for(i=0;i<g->size;i++)
    {
        dist[i] = MAX_INT;
        onstack[i]=0;
    }

    int source = 0;
    dist[source] = 0;

    std::deque<int> deq;
    deq.push_back(source);
    onstack[source]=1;

    printf("Pushed initial\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");

    flush_cache();
    start_timing();

    // make threads
    std::vector<std::thread> threads;
    for(i = 0; i < numThreads; ++i){
        threads.push_back(std::thread(dijkstra_LIFO_thread, g, dist, std::ref(deq), i, onstack, dist_locks));
    }

    for (auto it = threads.begin(); it != threads.end(); ++it) {
        std::thread &t = *it;
        t.join();
    }

    stop_timing();

#ifdef PRINT_DISTANCES
    i=0;
    while(i < g->size && i < 10)
    {
        printf("%d ", dist[i]);
        i++;
    }
    printf("\n");
#endif
    delete(onstack);
    delete(dist);
    delete(dist_locks);
}
Exemple #13
0
void external_dataset_sort(external_dataset_t* data)
{
    struct runtime rt;
    void* results = NULL;
    size_t i;
    
    stream_t* tmp;
    stream_t* stream = data->stream;
    stream_seek(stream, 0);
    tmp = stream_create(stream->config, "tmp.stream");
    stream_open(tmp, O_CREAT | O_TRUNC | O_RDWR | O_SYNC);
    /* sort each individual chunk of memory size */
    for(i = 0; i < data->n_records / MEMORY_RECORDS(stream); i++)
    {
        memory_read(stream, RECORDS(data->mem), MEMORY_RECORDS(stream));
        N_RECORDS(data->mem) = MEMORY_RECORDS(stream);
        results = NULL;
        start_timing(&rt);
        fp_im_sort(data->context, RECORDS(data->mem), N_RECORDS(data->mem), &results);
        stop_timing(&rt);
        printf("Sort time: %f\n", get_runtime(rt));
        memory_write(tmp, RECORDS(data->mem), N_RECORDS(data->mem));
        dataset_print(data->mem, TRUE);

    }
    if(data->n_records % MEMORY_RECORDS(stream))
    {
        memory_read(stream, RECORDS(data->mem), data->n_records % MEMORY_RECORDS(stream));
        N_RECORDS(data->mem) = data->n_records % MEMORY_RECORDS(stream);
        start_timing(&rt);
        results = NULL;
        fp_im_sort(data->context, RECORDS(data->mem), N_RECORDS(data->mem), &results);
        stop_timing(&rt);
        memory_write(tmp, RECORDS(data->mem), N_RECORDS(data->mem));
        dataset_print(data->mem, TRUE);
    }
    /* merge memory chunks block by block */
}
Exemple #14
0
void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 	start_timing();

	SetLighting();

	CALL_MEMBER_FN(bunny, bunny.render)();

	float timeElapsed = stop_timing();
  	gTotalFrames++;
  	gTotalTimeElapsed += timeElapsed;
  	float fps = gTotalFrames / gTotalTimeElapsed;
  	char string[1024] = {0};
  	sprintf(string, "OpenGL Bunny: %0.2f FPS", fps);
  	glutSetWindowTitle(string);

	glutPostRedisplay();
  	glutSwapBuffers();
}
Exemple #15
0
/**
 * @brief Performs a volume analysis.
 * @return Zero for success, negative value otherwise.
 */
int analyze(udefrag_job_parameters *jp)
{
    ULONGLONG time;
    int result;
    
    time = start_timing("analysis",jp);
    jp->pi.current_operation = VOLUME_ANALYSIS;
    
    /* update volume information */
    result = get_volume_information(jp);
    if(result < 0)
        return result;
    
    /* scan volume for free space areas */
    if(get_free_space_layout(jp) < 0)
        return (-1);
    
    /* redraw mft zone in light magenta */
    get_mft_zones_layout(jp);
    
    /* search for files */
    if(find_files(jp) < 0)
        return (-1);
    
    /* redraw well known locked files in green */
    redraw_well_known_locked_files(jp);

    /* produce list of fragmented files */
    produce_list_of_fragmented_files(jp);
    (void)check_fragmentation_level(jp); /* for debugging */

    result = check_requested_action(jp);
    if(result < 0)
        return result;
    
    jp->p_counters.analysis_time = winx_xtime() - time;
    stop_timing("analysis",time,jp);
    return 0;
}
static int __init tort_init(void)
{
	int err = 0, i, infinite = !cycles_count;
	int bad_ebs[ebcnt];

;
;
//	printk(PRINT_PREF "Warning: this program is trying to wear out your "
;
;
//	printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n",
;
	if (pgcnt)
//		printk(PRINT_PREF "torturing just %d pages per eraseblock\n",
;
;

	mtd = get_mtd_device(NULL, dev);
	if (IS_ERR(mtd)) {
		err = PTR_ERR(mtd);
;
		return err;
	}

	if (mtd->writesize == 1) {
//		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
;
		pgsize = 512;
	} else
		pgsize = mtd->writesize;

	if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) {
;
		goto out_mtd;
	}

	err = -ENOMEM;
	patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!patt_5A5) {
;
		goto out_mtd;
	}

	patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!patt_A5A) {
;
		goto out_patt_5A5;
	}

	patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!patt_FF) {
;
		goto out_patt_A5A;
	}

	check_buf = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!check_buf) {
;
		goto out_patt_FF;
	}

	err = 0;

	/* Initialize patterns */
	memset(patt_FF, 0xFF, mtd->erasesize);
	for (i = 0; i < mtd->erasesize / pgsize; i++) {
		if (!(i & 1)) {
			memset(patt_5A5 + i * pgsize, 0x55, pgsize);
			memset(patt_A5A + i * pgsize, 0xAA, pgsize);
		} else {
			memset(patt_5A5 + i * pgsize, 0xAA, pgsize);
			memset(patt_A5A + i * pgsize, 0x55, pgsize);
		}
	}

	/*
	 * Check if there is a bad eraseblock among those we are going to test.
	 */
	memset(&bad_ebs[0], 0, sizeof(int) * ebcnt);
	if (mtd->block_isbad) {
		for (i = eb; i < eb + ebcnt; i++) {
			err = mtd->block_isbad(mtd,
					       (loff_t)i * mtd->erasesize);

			if (err < 0) {
//				printk(PRINT_PREF "block_isbad() returned %d "
;
				goto out;
			}

			if (err) {
;
				bad_ebs[i - eb] = 1;
			}
		}
	}

	start_timing();
	while (1) {
		int i;
		void *patt;

		/* Erase all eraseblocks */
		for (i = eb; i < eb + ebcnt; i++) {
			if (bad_ebs[i - eb])
				continue;
			err = erase_eraseblock(i);
			if (err)
				goto out;
			cond_resched();
		}

		/* Check if the eraseblocks contain only 0xFF bytes */
		if (check) {
			for (i = eb; i < eb + ebcnt; i++) {
				if (bad_ebs[i - eb])
					continue;
				err = check_eraseblock(i, patt_FF);
				if (err) {
//					printk(PRINT_PREF "verify failed"
;
					goto out;
				}
				cond_resched();
			}
		}

		/* Write the pattern */
		for (i = eb; i < eb + ebcnt; i++) {
			if (bad_ebs[i - eb])
				continue;
			if ((eb + erase_cycles) & 1)
				patt = patt_5A5;
			else
				patt = patt_A5A;
			err = write_pattern(i, patt);
			if (err)
				goto out;
			cond_resched();
		}

		/* Verify what we wrote */
		if (check) {
			for (i = eb; i < eb + ebcnt; i++) {
				if (bad_ebs[i - eb])
					continue;
				if ((eb + erase_cycles) & 1)
					patt = patt_5A5;
				else
					patt = patt_A5A;
				err = check_eraseblock(i, patt);
				if (err) {
//					printk(PRINT_PREF "verify failed for %s"
//					       " pattern\n",
//					       ((eb + erase_cycles) & 1) ?
;
					goto out;
				}
				cond_resched();
			}
		}

		erase_cycles += 1;

		if (erase_cycles % gran == 0) {
			long ms;

			stop_timing();
			ms = (finish.tv_sec - start.tv_sec) * 1000 +
			     (finish.tv_usec - start.tv_usec) / 1000;
//			printk(PRINT_PREF "%08u erase cycles done, took %lu "
//			       "milliseconds (%lu seconds)\n",
;
			start_timing();
		}

		if (!infinite && --cycles_count == 0)
			break;
	}
out:

//	printk(PRINT_PREF "finished after %u erase cycles\n",
;
	kfree(check_buf);
out_patt_FF:
	kfree(patt_FF);
out_patt_A5A:
	kfree(patt_A5A);
out_patt_5A5:
	kfree(patt_5A5);
out_mtd:
	put_mtd_device(mtd);
	if (err)
;
;
	return err;
}
Exemple #17
0
int
main(void)
{
    struct timespec ts, ts2;
    int error;
    long long count = 0;
    long long max;
    int j;
    int cpuno;
    int ncpu;
    int *done;
    size_t ncpu_size;

    done = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
                MAP_SHARED|MAP_ANON, -1, 0);

    /*
     * How many cpu threads are there?
     */
    ncpu = 0;
    ncpu_size = sizeof(ncpu);
    if (sysctlbyname("hw.ncpu", &ncpu, &ncpu_size, NULL, 0) < 0) {
        perror("sysctl hw.ncpu");
        exit(1);
    }
    printf("timing standard getuid() syscall, %d threads\n", ncpu);
    printf("if using powerd, run several times\n");
    *done = 0;

    /*
     * Approximate timing run length
     */
    start_timing();
    while (stop_timing(0, NULL) == 0) {
        for (j = 0; j < 100; ++j)
            getuid();
        count += 100;
    }
    max = count;

    /*
     * Run same length on all threads.
     */
    for (cpuno = 0; cpuno < ncpu; ++cpuno) {
        if (fork() == 0) {
            /*
             * Give scheduler time to move threads around
             */
            start_timing();
            while (stop_timing(0, NULL) == 0) {
                for (j = 0; j < 100; ++j)
                    getuid();
            }

            /*
             * Actual timing test is here.
             */
            start_timing();
            for (count = 0; count < max; count += 100) {
                for (j = 0; j < 100; ++j)
                    getuid();
            }
            stop_timing(count, "getuid() sysmsg");

            /*
             * Don't unbusy the cpu until the other threads are
             * done.
             */
            atomic_add_int(done, 1);
            while (*done < ncpu)	/* wait for other threads */
                getuid();
            exit(0);
        }
    }
    while (wait3(NULL, 0, NULL) > 0 || errno == EINTR)
        ;
    return 0;
}
Exemple #18
0
int main(int argc, char **argv)
{
    iENTER;
    //FSTREAM_READER_STATE    *preader_state = NULL;
    //FSTREAM_WRITER_STATE    *pwriter_state = NULL;
    ION_STREAM              *output_stream = NULL;
    ION_STREAM              *input_stream = NULL;
    hWRITER                  hwriter = 0;
    hREADER                  hreader = 0;
    
    ION_STRING               temp;
    char                    *name = NULL;
    ION_TYPE                 t = (ION_TYPE)999;
    int32_t                  symbol_table_count = 0;
    int                      ii, non_argc = 0;
    char                   **non_argv = NULL;


    ION_STRING_INIT(&temp);

    // read the command line for any instruction the caller might have
    non_argv = (char**)malloc(argc * sizeof(char*));
    process_args(argc, argv, non_argv, &non_argc);
    if (g_print_help) SUCCEED();

    // clear the option structs and set them appropriately
    memset(&g_reader_options, 0, sizeof(g_reader_options));
    memset(&g_writer_options, 0, sizeof(g_writer_options));
    g_writer_options.pretty_print     = TRUE;
    
    // set up our debug options
    if (g_dump_args) dump_arg_globals();

    if (g_timer) {
        start_timing();
    }

    // read in the catalog, if there is one
    if (g_catalogs) {
        CHECK( load_catalog_list(&g_hcatalog), "load a catalog file" );
        CHECK(ion_catalog_get_symbol_table_count(g_hcatalog, &symbol_table_count), "get the symbol table count from the loaded catalog");
        fprintf(stderr, "Catalog loaded %d symbol tables\n", symbol_table_count);
    }
    else {
        CHECK( ion_catalog_open( &g_hcatalog ), "open empty catalog" );
    }
    g_reader_options.pcatalog = (ION_CATALOG *)g_hcatalog; // HACK - TODO - HOW SHOULD WE HANDLE THIS? - either the options
    g_writer_options.pcatalog = (ION_CATALOG *)g_hcatalog; // HACK - TODO - should have an hcatalog or we need a h to p fn


    // if we're updating an existing catalog load it
    if (g_update_symtab) {
        // load specified symbol table
        CHECK( load_symbol_table(&g_hsymtab, g_update_symtab), "load symbol table to update");
    }
    else {
        // othwerwise we need to init a symbol table to update
        CHECK( initialize_new_symbol_table(&g_hsymtab), "initialize a new (empty) symbol table to fill" );
    }

    // open the output stream writer attached to stdout
    // TODO: allow caller to specify the output file on the command line
    CHECK( ion_stream_open_stdout( &output_stream ), "ion stream open stdout failed");
    CHECK( ion_writer_open( &hwriter, output_stream, &g_writer_options), "ion writer open failed");
    //CHECK( ion_writer_open_fstream(&pwriter_state, stdout, &g_writer_options), "writer open failed");

    // now, do we process from stdin or from file names on the command line
    if (non_argc > 0) {
        // file names
        for (ii=0; ii<non_argc; ii++) {
            // open our input and output streams (reader and writer)
            CHECK( process_filename(non_argv[ii], &g_reader_options), "process filename failed" );
        }
    }
    else {
        // from stdin
        // open our input and output streams (reader and writer)
        CHECK( ion_stream_open_stdin( &input_stream ), "open stdin as an ION_STREAM failed");
        CHECK( ion_reader_open(&hreader, input_stream, &g_reader_options), "open stdin as an ion reader failed");
        //CHECK( ion_reader_open_fstream(&preader_state, stdin, &g_reader_options), "reader open stdin failed");
        CHECKREADER( process_input_reader(hreader), "process stdin", hreader );
        CHECK( ion_reader_close( hreader ), "closing the ion reader");
        CHECK( ion_stream_close( input_stream), "closing the input stream");
        // CHECK( ion_reader_close_fstream( preader_state ), "closing the reader");
    }

    // if we're emitting a symbol table we need to actually output the 
    // table now (we only collected the symbols from the input sources 
    // during the pass above
    CHECK( symbol_table_write( hwriter ), "emit the new symbol table we've built up" );

    // close up
    //CHECK( ion_writer_close_fstream( pwriter_state ), "closing the writer");
    CHECK( ion_writer_close( hwriter ), "closing the ion writer");
    CHECK( ion_stream_close( output_stream ), "closing the ion output stream");

    if (g_hsymtab)  CHECK(ion_symbol_table_close(g_hsymtab), "closing the temp symbol table");
    if (g_hcatalog) CHECK(ion_catalog_close(g_hcatalog), "closing the catalog");
    SUCCEED();
    
fail:// this is iRETURN expanded so I can set a break point on it
    if (g_debug) {
        fprintf(stderr, "\nionsymbols finished, returning err [%d] = \"%s\", %d\n", err, ion_error_to_str(err), (intptr_t)t);
    }

    if (g_timer) {
        stop_timing();
    }

    if (non_argv) free(non_argv);
    return err;
}
Exemple #19
0
int
main(int ac, char **av)
{
    long long count = 0;
    long long max;
    char c;
    int j;
    int loops;
    int bytes;
    int ppri = 999;
    int fds[2];
    char *buf;
    char *ptr;
    char *msg = "datarate";

    if (ac == 1) {
	fprintf(stderr, "%s blocksize[k,m] [pipe_writer_pri] [msg]\n", av[0]);
	exit(1);
    }
    bytes = strtol(av[1], &ptr, 0);
    if (*ptr == 'k' || *ptr == 'K') {
	bytes *= 1024;
    } else if (*ptr == 'm' || *ptr == 'M') {
	bytes *= 1024 * 1024;
    } else if (*ptr) {
	fprintf(stderr, "Illegal numerical suffix: %s\n", ptr);
	exit(1);
    }
    if (bytes <= 0) {
	fprintf(stderr, "I can't handle %d sized buffers\n", bytes);
	exit(1);
    }
    if (ac >= 3)
	ppri = strtol(av[2], NULL, 0);
    if (ac >= 4)
	msg = av[3];

    buf = mmap(NULL, bytes * 2 + PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
    if (buf == MAP_FAILED) {
	perror("mmap/buffer");
	exit(1);
    }

    bzero(buf, bytes * 2 + PAGE_SIZE);

    printf("tests one-way pipe using direct-write buffer\n");
    if (pipe(fds)) {
	perror("pipe");
	exit(1);
    }
    if (fork() == 0) {
	/*
	 * child process
	 */
	int n;
	int i;

	close(fds[0]);
	buf += (bytes + PAGE_MASK) & ~PAGE_MASK;
	i = 0;
	for (;;) {
	    n = read(fds[1], buf + i, bytes - i);
	    if (n <= 0)
		break;
	    if (n + i == bytes)
		i = 0;
	    else
		i += n;
	}
	_exit(0);
    } else {
	/* 
	 * parent process.
	 */
	if (ppri != 999) {
	    if (setpriority(PRIO_PROCESS, getpid(), ppri) < 0) {
		perror("setpriority");
		exit(1);
	    }
	}
	close(fds[1]);

	/*
	 * Figure out how many loops it takes for 1 second's worth.
	 */
	start_timing();
	for (j = 0; ; ++j) {
	    if (write(fds[0], buf, bytes) != bytes) {
		perror("write");
		exit(1);
	    }
	    if ((j & 31) == 0 && stop_timing(0, NULL))
		break;
	}
	loops = j * 2 + 1;
	loops *= 2;
	usleep(1000000 / 10);
	start_timing();

	for (j = loops; j; --j) {
	    if (write(fds[0], buf, bytes) != bytes) {
		perror("write");
		exit(1);
	    }
	}
	close(fds[0]);
	while(wait(NULL) >= 0)
	    ;
	stop_timing(loops, "full duplex pipe / %dK bufs:", bytes / 1024);
	printf("%s: blkSize %d %5.2f MBytes/sec\n",
		msg,
		bytes,
		(double)loops * bytes * 1000000.0 / 
		(1024.0 * 1024.0 * get_timing()));
    }
    return(0);
}
static int __init tort_init(void)
{
	int err = 0, i, infinite = !cycles_count;
	int bad_ebs[ebcnt];

	printk(KERN_INFO "\n");
	printk(KERN_INFO "=================================================\n");
	printk(PRINT_PREF "Warning: this program is trying to wear out your "
	       "flash, stop it if this is not wanted.\n");
	printk(PRINT_PREF "MTD device: %d\n", dev);
	printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n",
	       ebcnt, eb, eb + ebcnt - 1, dev);
	if (pgcnt)
		printk(PRINT_PREF "torturing just %d pages per eraseblock\n",
			pgcnt);
	printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled");

	mtd = get_mtd_device(NULL, dev);
	if (IS_ERR(mtd)) {
		err = PTR_ERR(mtd);
		printk(PRINT_PREF "error: cannot get MTD device\n");
		return err;
	}

	if (mtd->writesize == 1) {
		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
		       "bytes.\n");
		pgsize = 512;
	} else
		pgsize = mtd->writesize;

	if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) {
		printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt);
		goto out_mtd;
	}

	err = -ENOMEM;
	patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!patt_5A5) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out_mtd;
	}

	patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!patt_A5A) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out_patt_5A5;
	}

	patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!patt_FF) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out_patt_A5A;
	}

	check_buf = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!check_buf) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out_patt_FF;
	}

	err = 0;

	/* Initialize patterns */
	memset(patt_FF, 0xFF, mtd->erasesize);
	for (i = 0; i < mtd->erasesize / pgsize; i++) {
		if (!(i & 1)) {
			memset(patt_5A5 + i * pgsize, 0x55, pgsize);
			memset(patt_A5A + i * pgsize, 0xAA, pgsize);
		} else {
			memset(patt_5A5 + i * pgsize, 0xAA, pgsize);
			memset(patt_A5A + i * pgsize, 0x55, pgsize);
		}
	}

	/*
	 * Check if there is a bad eraseblock among those we are going to test.
	 */
	memset(&bad_ebs[0], 0, sizeof(int) * ebcnt);
	if (mtd->block_isbad) {
		for (i = eb; i < eb + ebcnt; i++) {
			err = mtd->block_isbad(mtd,
					       (loff_t)i * mtd->erasesize);

			if (err < 0) {
				printk(PRINT_PREF "block_isbad() returned %d "
				       "for EB %d\n", err, i);
				goto out;
			}

			if (err) {
				printk("EB %d is bad. Skip it.\n", i);
				bad_ebs[i - eb] = 1;
			}
		}
	}

	start_timing();
	while (1) {
		int i;
		void *patt;

		/* Erase all eraseblocks */
		for (i = eb; i < eb + ebcnt; i++) {
			if (bad_ebs[i - eb])
				continue;
			err = erase_eraseblock(i);
			if (err)
				goto out;
			cond_resched();
		}

		/* Check if the eraseblocks contain only 0xFF bytes */
		if (check) {
			for (i = eb; i < eb + ebcnt; i++) {
				if (bad_ebs[i - eb])
					continue;
				err = check_eraseblock(i, patt_FF);
				if (err) {
					printk(PRINT_PREF "verify failed"
					       " for 0xFF... pattern\n");
					goto out;
				}
				cond_resched();
			}
		}

		/* Write the pattern */
		for (i = eb; i < eb + ebcnt; i++) {
			if (bad_ebs[i - eb])
				continue;
			if ((eb + erase_cycles) & 1)
				patt = patt_5A5;
			else
				patt = patt_A5A;
			err = write_pattern(i, patt);
			if (err)
				goto out;
			cond_resched();
		}

		/* Verify what we wrote */
		if (check) {
			for (i = eb; i < eb + ebcnt; i++) {
				if (bad_ebs[i - eb])
					continue;
				if ((eb + erase_cycles) & 1)
					patt = patt_5A5;
				else
					patt = patt_A5A;
				err = check_eraseblock(i, patt);
				if (err) {
					printk(PRINT_PREF "verify failed for %s"
					       " pattern\n",
					       ((eb + erase_cycles) & 1) ?
					       "0x55AA55..." : "0xAA55AA...");
					goto out;
				}
				cond_resched();
			}
		}

		erase_cycles += 1;

		if (erase_cycles % gran == 0) {
			long ms;

			stop_timing();
			ms = (finish.tv_sec - start.tv_sec) * 1000 +
			     (finish.tv_usec - start.tv_usec) / 1000;
			printk(PRINT_PREF "%08u erase cycles done, took %lu "
			       "milliseconds (%lu seconds)\n",
			       erase_cycles, ms, ms / 1000);
			start_timing();
		}

		if (!infinite && --cycles_count == 0)
			break;
	}
out:

	printk(PRINT_PREF "finished after %u erase cycles\n",
	       erase_cycles);
	kfree(check_buf);
out_patt_FF:
	kfree(patt_FF);
out_patt_A5A:
	kfree(patt_A5A);
out_patt_5A5:
	kfree(patt_5A5);
out_mtd:
	put_mtd_device(mtd);
	if (err)
		printk(PRINT_PREF "error %d occurred during torturing\n", err);
	printk(KERN_INFO "=================================================\n");
	return err;
}
static int __init fsspeed_init(void)
{
	int err, i;
	long speed;
	struct file *fp;
	mm_segment_t fs;

	printk(KERN_INFO "\n");
	printk(KERN_INFO "=================================================\n");
	printk(PRINT_PREF "rw %d PAGES using file: %s\n", count, fname);

	err = -ENOMEM;
	iobuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!iobuf) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out;
	}

	simple_srand(1);
	set_random_data(iobuf, PAGE_SIZE);

	fp = filp_open(fname, O_RDWR|O_CREAT, 0600);
	if (IS_ERR(fp)) {
		printk("open file %s failed.\n", fname);
		err = PTR_ERR(fp);
		goto out;
	}

	/* Write all eraseblocks, 1 eraseblock at a time */
	printk(PRINT_PREF "testing file system write speed\n");
	fs = get_fs();
	set_fs(KERNEL_DS);
	start_timing();
	for (i = 0; i < count; ++i) {
		err = vfs_write(fp, iobuf, PAGE_SIZE, &fp->f_pos);
		if (err < 0)
			goto out2;
//		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "write speed is %ld KiB/s\n", speed);
	
	vfs_fsync(fp, fp->f_path.dentry, 0);
	invalidate_mapping_pages(fp->f_dentry->d_inode->i_mapping, 0, -1);
	vfs_llseek(fp, 0, SEEK_SET);
	
	/* Read all eraseblocks, 1 eraseblock at a time */
	printk(PRINT_PREF "testing file system read speed\n");
	start_timing();
	for (i = 0; i < count; ++i) {
		err = vfs_read(fp, iobuf, PAGE_SIZE, &fp->f_pos);
		if (err < 0)
			goto out2;
//		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "read speed is %ld KiB/s\n", speed);

	printk(PRINT_PREF "finished\n");
	err = 0;
out2:
	filp_close(fp, NULL);
	set_fs(fs);
out:
	kfree(iobuf);
	if (err)
		printk(PRINT_PREF "error %d occurred\n", err);
	printk(KERN_INFO "=================================================\n");
	return err;
}
void dijkstra_workstealing(CSRGraph *g, int numThreads)
{
    int *dist = new int[g->size];
    std::mutex *dist_locks = new std::mutex[g->size];
    std::mutex *queue_locks = new std::mutex[g->size];
    int i;

    for(i=0;i<g->size;i++)
    {
        dist[i] = MAX_INT;
    }

    int source = 0;
    dist[source] = 0;


    Thread_struct ithread_struct;
    //fill up the thread struct
    Priority_struct original_node;
    original_node.node_name=source;
    original_node.node_weight=0;
    ithread_struct.thread_queue.push(original_node);
    ithread_struct.thread_id=1;
    queue_vector.push_back(ithread_struct);


    flush_cache();
    start_timing();

    // make threads
    std::vector<std::thread> threads;
    threads.push_back(std::thread(dijkstra_workstealing_thread, g, dist,1, dist_locks, queue_locks));
    //    }

    for(int i=2; i <numThreads; ++i){
       Thread_struct tthread_struct;
       tthread_struct.thread_id=i;
       queue_vector.push_back(tthread_struct);
       threads.push_back(std::thread(dijkstra_workstealing_thread, g , dist, i, dist_locks, queue_locks));
}
    for (auto it = threads.begin(); it != threads.end(); ++it) {
        std::thread &t = *it;
        t.join();
    }

stop_timing();

#ifdef PRINT_DISTANCES
i=0;
while(i < g->size && i < 10)
{
    printf("%d ", dist[i]);
    i++;
}
printf("\n");
#endif

delete(dist);
//delete(dist_locks);
//delete(queue_locks);
dist = NULL;

}
void dijkstra_FIFO_nothreads(CSRGraph *g)
{
    int *dist = new int[g->size];
    int i;
    for(i=0;i<g->size;i++)
    {
        dist[i] = MAX_INT;
    }

    int source = 0;
    dist[source] = 0;

    std::deque<int> deq;
    deq.push_back(source);

    printf("\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");

    flush_cache();
    start_timing();

    while(! deq.empty() )
    {
        int u = deq.front();
        deq.pop_front();
	
    printf("Popped\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");

        std::vector<int> neighbors = CSRGraph_getNeighbors(g, u);
        int neighbor;
        for(neighbor=0;neighbor < neighbors.size(); neighbor++)
        {
            int v = neighbors[neighbor];
            int alt = dist[u] + CSRGraph_getDistance(g, u, v);

            if(alt < dist[v])
            {
                dist[v] = alt;
                deq.push_back(v);
		
    printf("Pushed\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");
            }      
        }
    }

    stop_timing();

    //Print calculated distances to each graph
    i=0;
    while(i < g->size && i < 10)
    {
        printf("%d ", dist[i]);
        i++;
    }
    printf("\n");

    delete(dist);
    dist = NULL;
}
void dijkstra_LIFO_nothreads(CSRGraph *g)
{
    int *dist = new int[g->size];
    int *onstack = new int[g->size];
    int i;

    for(i=0;i<g->size;i++)
    {
        dist[i] = MAX_INT;
        onstack[i]= 0;
    }

    int source = 0;
    dist[source] = 0;

    std::deque<int> deq;
    deq.push_back(source);
    onstack[source] = 1;
    
    printf("Pushed initial\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");

    flush_cache();
    start_timing();

    // *** perform DFS ***
    while(! deq.empty() )
    {
        int u = deq.back();
        deq.pop_back();
	
    printf("Popped\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");
        onstack[u] = 0;

        std::vector<int> neighbors = CSRGraph_getNeighbors(g, u);
        int neighbor;
        for(neighbor=0;neighbor < neighbors.size(); neighbor++)
        {
            int v = neighbors[neighbor];
            int alt = dist[u] + CSRGraph_getDistance(g, u, v);
            if(alt < dist[v])
            {
                dist[v] = alt;

                if(onstack[v] == 0)
                {
                    deq.push_back(v);
		    
    printf("Pushed\n");
    for(int i=0; i< deq.size();i++){
	printf(" %d", deq[i]);
    }
    printf("\n");
                    onstack[v] = 1;
                }
            }
        }
    }

    stop_timing();

#ifdef PRINT_DISTANCES
    i=0;
    while(i < g->size && i < 10)
    {
        printf("%d ", dist[i]);
        i++;
    }
    printf("\n");
#endif

    delete(onstack);
    delete(dist);
    dist = NULL;
}
void dijkstra_pq_nothreads(CSRGraph *g)
{
    int *dist = new int[g->size];
    int *visited = new int[g->size];
    int *changed = new int[g->size];

    int i;
    for(i=0;i<g->size;i++)
    {
        dist[i] = MAX_INT;
        visited[i] = 0;
        changed[i]= 0;
    }

    int source = 0;
    dist[source] = 0;
    visited[source] = 1;
    changed[source] = 1;

    std::priority_queue<Priority_struct, std::vector<Priority_struct>, Compare_priority> pq;
    Priority_struct temp;
    temp.node_name=source;
    temp.node_weight=0;
    pq.push(temp);
    
    printf("Pushed\n");
    for(int i=0; i< pq.size();i++){
	printf(" %d", pq[i].node_name);
    }

    printf("\n");

    flush_cache();
    start_timing();

    // *** perform DFS ***
    while(!pq.empty() )
    {
        Priority_struct temp_struct = pq.top();
        int u = temp_struct.node_name;
        pq.pop();
	
    printf("Popped\n");
    for(int i=0; i< pq.size();i++){
	printf(" %d", pq[i]);
    }
    printf("\n");

        std::vector<int> neighbors = CSRGraph_getNeighbors(g, u);
        int neighbor;
        for(neighbor=0;neighbor < neighbors.size(); neighbor++)
        {
            int v = neighbors[neighbor];
            int alt = dist[u] + CSRGraph_getDistance(g, u, v);

            if(alt < dist[v])
            {
                Priority_struct temp2;
                temp2.node_name=v;
                temp2.node_weight= CSRGraph_getDistance(g, u, v); 
                dist[v] = alt;
                changed[v]++;
                visited[v]++;    
                pq.push(temp2);
		
    printf("Pushed\n");
    for(int i=0; i< pq.size();i++){
	printf(" %d", pq[i]);
    }
    printf("\n");
            }

        }
    }

    stop_timing();

#ifdef PRINT_DISTANCES
    i=0;
    while(i < g->size && i < 10)
    {

        printf("%d ", dist[i]);
        i++;
    }
    printf("\n");
#endif

    delete(dist);
    delete(visited);
    delete(changed);
}
static int __init mtd_speedtest_init(void)
{
	int err, i, blocks, j, k;
	long speed;
	uint64_t tmp;

	printk(KERN_INFO "\n");
	printk(KERN_INFO "=================================================\n");

	if (dev < 0) {
		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
		return -EINVAL;
	}

	if (count)
		printk(PRINT_PREF "MTD device: %d    count: %d\n", dev, count);
	else
		printk(PRINT_PREF "MTD device: %d\n", dev);

	mtd = get_mtd_device(NULL, dev);
	if (IS_ERR(mtd)) {
		err = PTR_ERR(mtd);
		printk(PRINT_PREF "error: cannot get MTD device\n");
		return err;
	}

	if (mtd->writesize == 1) {
		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
		       "bytes.\n");
		pgsize = 512;
	} else
		pgsize = mtd->writesize;

	tmp = mtd->size;
	do_div(tmp, mtd->erasesize);
	ebcnt = tmp;
	pgcnt = mtd->erasesize / pgsize;

	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
	       "page size %u, count of eraseblocks %u, pages per "
	       "eraseblock %u, OOB size %u\n",
	       (unsigned long long)mtd->size, mtd->erasesize,
	       pgsize, ebcnt, pgcnt, mtd->oobsize);

	if (count > 0 && count < ebcnt)
		ebcnt = count;

	err = -ENOMEM;
	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!iobuf) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out;
	}

	simple_srand(1);
	set_random_data(iobuf, mtd->erasesize);

	err = scan_for_bad_eraseblocks();
	if (err)
		goto out;

	err = erase_whole_device();
	if (err)
		goto out;

	/* Write all eraseblocks, 1 eraseblock at a time */
	printk(PRINT_PREF "testing eraseblock write speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = write_eraseblock(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed);

	/* Read all eraseblocks, 1 eraseblock at a time */
	printk(PRINT_PREF "testing eraseblock read speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = read_eraseblock(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed);

	err = erase_whole_device();
	if (err)
		goto out;

	/* Write all eraseblocks, 1 page at a time */
	printk(PRINT_PREF "testing page write speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = write_eraseblock_by_page(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed);

	/* Read all eraseblocks, 1 page at a time */
	printk(PRINT_PREF "testing page read speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = read_eraseblock_by_page(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed);

	err = erase_whole_device();
	if (err)
		goto out;

	/* Write all eraseblocks, 2 pages at a time */
	printk(PRINT_PREF "testing 2 page write speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = write_eraseblock_by_2pages(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed);

	/* Read all eraseblocks, 2 pages at a time */
	printk(PRINT_PREF "testing 2 page read speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = read_eraseblock_by_2pages(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed);

	/* Erase all eraseblocks */
	printk(PRINT_PREF "Testing erase speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = erase_eraseblock(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed);

	/* Multi-block erase all eraseblocks */
	for (k = 1; k < 7; k++) {
		blocks = 1 << k;
		printk(PRINT_PREF "Testing %dx multi-block erase speed\n",
		       blocks);
		start_timing();
		for (i = 0; i < ebcnt; ) {
			for (j = 0; j < blocks && (i + j) < ebcnt; j++)
				if (bbt[i + j])
					break;
			if (j < 1) {
				i++;
				continue;
			}
			err = multiblock_erase(i, j);
			if (err)
				goto out;
			cond_resched();
			i += j;
		}
		stop_timing();
		speed = calc_speed();
		printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n",
		       blocks, speed);
	}
	printk(PRINT_PREF "finished\n");
out:
	kfree(iobuf);
	kfree(bbt);
	put_mtd_device(mtd);
	if (err)
		printk(PRINT_PREF "error %d occurred\n", err);
	printk(KERN_INFO "=================================================\n");
	return err;
}
static int __init mtd_speedtest_init(void)
{
	int err, i;
	long speed;
	uint64_t tmp;

	printk(KERN_INFO "\n");
	printk(KERN_INFO "=================================================\n");
	printk(PRINT_PREF "MTD device: %d\n", dev);

	mtd = get_mtd_device(NULL, dev);
	if (IS_ERR(mtd)) {
		err = PTR_ERR(mtd);
		printk(PRINT_PREF "error: cannot get MTD device\n");
		return err;
	}

	if (mtd->writesize == 1) {
		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
		       "bytes.\n");
		pgsize = 512;
	} else
		pgsize = mtd->writesize;

	tmp = mtd->size;
	do_div(tmp, mtd->erasesize);
	ebcnt = tmp;
	pgcnt = mtd->erasesize / pgsize;

	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
	       "page size %u, count of eraseblocks %u, pages per "
	       "eraseblock %u, OOB size %u\n",
	       (unsigned long long)mtd->size, mtd->erasesize,
	       pgsize, ebcnt, pgcnt, mtd->oobsize);

	err = -ENOMEM;
	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
	if (!iobuf) {
		printk(PRINT_PREF "error: cannot allocate memory\n");
		goto out;
	}

	simple_srand(1);
	set_random_data(iobuf, mtd->erasesize);

	err = scan_for_bad_eraseblocks();
	if (err)
		goto out;

	err = erase_whole_device();
	if (err)
		goto out;

	/* Write all eraseblocks, 1 eraseblock at a time */
	printk(PRINT_PREF "testing eraseblock write speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = write_eraseblock(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed);

	/* Read all eraseblocks, 1 eraseblock at a time */
	printk(PRINT_PREF "testing eraseblock read speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = read_eraseblock(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed);

	err = erase_whole_device();
	if (err)
		goto out;

	/* Write all eraseblocks, 1 page at a time */
	printk(PRINT_PREF "testing page write speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = write_eraseblock_by_page(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed);

	/* Read all eraseblocks, 1 page at a time */
	printk(PRINT_PREF "testing page read speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = read_eraseblock_by_page(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed);

	err = erase_whole_device();
	if (err)
		goto out;

	/* Write all eraseblocks, 2 pages at a time */
	printk(PRINT_PREF "testing 2 page write speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = write_eraseblock_by_2pages(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed);

	/* Read all eraseblocks, 2 pages at a time */
	printk(PRINT_PREF "testing 2 page read speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = read_eraseblock_by_2pages(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed);

	/* Erase all eraseblocks */
	printk(PRINT_PREF "Testing erase speed\n");
	start_timing();
	for (i = 0; i < ebcnt; ++i) {
		if (bbt[i])
			continue;
		err = erase_eraseblock(i);
		if (err)
			goto out;
		cond_resched();
	}
	stop_timing();
	speed = calc_speed();
	printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed);

	printk(PRINT_PREF "finished\n");
out:
	kfree(iobuf);
	kfree(bbt);
	put_mtd_device(mtd);
	if (err)
		printk(PRINT_PREF "error %d occurred\n", err);
	printk(KERN_INFO "=================================================\n");
	return err;
}