/alps/fwbench

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/fwbench
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
1
#define _BSD_SOURCE
1 by Suren A. Chilingaryan
Initial release
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#include <errno.h>
6
#include <fcntl.h>
7
#include <glib.h>
8
#include <math.h>
9
#include <unistd.h>
10
#include <sys/stat.h>
11
#include <sys/time.h>
3 by Suren A. Chilingaryan
getopt support
12
#include <getopt.h>
13
#include <stdarg.h>
1 by Suren A. Chilingaryan
Initial release
14
15
#include <fastwriter.h>
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
16
17
#ifdef USE_UFO_GENERATOR
18
# include <ufo/ufo-graph.h>
19
#endif /* USE_UFO_GENERATOR */
1 by Suren A. Chilingaryan
Initial release
20
21
#include "config.h"
22
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
23
//#define USE_FIFO
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
24
#define WRITE_RANDOM "/dev/frandom"
1 by Suren A. Chilingaryan
Initial release
25
#define WRITE_INTERVAL 1
26
#define WRITE_SUMMARY 5
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
27
#define DELTA_TOLERANCE 5
1 by Suren A. Chilingaryan
Initial release
28
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
29
#ifdef USE_UFO_GENERATOR
30
# ifndef USE_FIFO
31
#  define USE_FIFO
32
# endif /* !USE_FIFO */
33
#endif /* USE_UFO_GENERATOR */
1 by Suren A. Chilingaryan
Initial release
34
35
const char *fifo_name = ".fifo";
36
37
struct setup_s {
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
38
    size_t uc;
1 by Suren A. Chilingaryan
Initial release
39
    size_t width;
40
    size_t height;
41
    size_t bpp;
42
    size_t fps;
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
43
3 by Suren A. Chilingaryan
getopt support
44
    size_t fpf;
1 by Suren A. Chilingaryan
Initial release
45
    size_t iters;
3 by Suren A. Chilingaryan
getopt support
46
    double tolerance;
47
    const char *output;
48
    const char *fs;
49
    
50
    int verbose;
1 by Suren A. Chilingaryan
Initial release
51
52
    volatile int run_started;
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
53
54
    struct timeval tv_started;
55
    struct timeval tv_last_written;
56
57
    int broken_frame;
58
    unsigned long frames, lost;
59
    unsigned long last_frames, last_lost;
60
61
    size_t frame_size;
62
    size_t num_read;
63
    size_t buf_max;
64
    
65
    size_t writeouts;
66
    
67
    fastwriter_t *fw;
3 by Suren A. Chilingaryan
getopt support
68
    char *current_output;
1 by Suren A. Chilingaryan
Initial release
69
};
70
71
typedef struct setup_s setup_t;
72
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
73
3 by Suren A. Chilingaryan
getopt support
74
75
typedef enum {
76
    OPT_OUTPUT = 'o',
77
    OPT_BUFFER = 'b',
78
    OPT_SIZE = 's',
79
    OPT_TIME = 't',
80
    OPT_RATE = 'r',
81
    OPT_FRAMES = 'n',
82
    OPT_GEOMETRY = 'g',
83
    OPT_FPF = 'f',
84
    OPT_MISSING = 'm',
85
    OPT_QUIET = 'q',
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
86
    OPT_UC = 'u',
3 by Suren A. Chilingaryan
getopt support
87
    OPT_HELP = 'h'
88
} options_t;
89
90
91
void Usage(int argc,  char* const argv[], const char *format, ...) {
92
    if (format) {
93
	va_list ap;
94
    
95
	va_start(ap, format);
96
	printf("Error %i: ", errno);
97
	vprintf(format, ap);
98
	printf("\n");
99
	va_end(ap);
100
    
101
        printf("\n");
102
    }
103
104
    printf(
105
"Usage:\n"
106
" %s [options]\n"
107
"   -o <file|device>	- Output to file/device [/dev/null]\n"
108
"			use %%zu to replace with frame number\n"
109
"   -f <number>		- Number of frames per file [all]\n"
110
"   -b size		- Buffer Size (MB)\n"
111
"   -r rate		- Write rate (MB/s)\n"
112
"   -s size		- Total size of data to write (GB)\n"
113
"   -t run_time		- Run time (s)\n"
114
"   -n frames		- Number of frames to write\n"
115
"   -g <width>x<height>	- Geometry [1024]\n"
116
"   -g <pixels>		- Number of megapixels [0.7]\n"
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
117
"   -m <percent>		- Tolerable missing frames  [100%%]\n"
118
"   -u <size>		- Use uncompressable data, repeating block (MB)\n"
3 by Suren A. Chilingaryan
getopt support
119
"   -q			- Quiete\n"
120
"   -h			- Help\n"
121
"\n\n",
122
argv[0]);
123
124
    exit(0);
125
}
126
127
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
128
#ifdef USE_UFO_GENERATOR
129
static void handle_error(GError *error) {
1 by Suren A. Chilingaryan
Initial release
130
    if (error != NULL) {
131
        g_print("%s\n", error->message); 
132
        g_error_free(error);
133
        exit(EXIT_FAILURE);
134
    }
135
}
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
136
#endif /* USE_UFO_GENERATOR */
137
3 by Suren A. Chilingaryan
getopt support
138
static void set_verbosity(setup_t *setup, int level) {
139
    setup->verbose = level;
140
}
141
142
static void set_current_output(setup_t *setup, size_t frame) {
143
    sprintf(setup->current_output, setup->output, frame);
144
}
145
146
static void set_output(setup_t *setup, const char *name) {
147
    setup->output = name;
148
    setup->fs = name;
149
    setup->current_output = malloc(strlen(setup->output) + 32);
150
    g_assert(setup->current_output);
151
    set_current_output(setup, 0);
152
}
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
153
154
static void set_dim(setup_t *setup, size_t width, size_t height) {
1 by Suren A. Chilingaryan
Initial release
155
    setup->bpp = sizeof(float);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
156
    setup->width = width;
157
    setup->height = height;
158
159
    setup->frame_size = setup->width * setup->height * setup->bpp;
160
}
161
3 by Suren A. Chilingaryan
getopt support
162
static void set_pixels(setup_t *setup, size_t pixels) {
163
    int width = sqrt(4 * pixels / 3);
164
    set_dim(setup, width, width * 3 / 4);
165
}
166
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
167
static void set_speed(setup_t *setup, size_t speed) {
1 by Suren A. Chilingaryan
Initial release
168
    setup->fps = 1 + speed / setup->width / setup->height / setup->bpp;
169
}
170
3 by Suren A. Chilingaryan
getopt support
171
static void set_iters(setup_t *setup, size_t iters) {
172
    setup->iters = iters;
173
}
174
175
static void set_time(setup_t *setup, size_t run_time) {
176
    setup->iters = run_time * setup->fps;
177
}
178
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
179
static void set_size(setup_t *setup, size_t size) {
4 by Suren A. Chilingaryan
Fix handling of size argument
180
    setup->iters = size / setup->frame_size + ((size % setup->frame_size)?1:0);
3 by Suren A. Chilingaryan
getopt support
181
}
182
183
static void set_frames_per_file(setup_t *setup, size_t fpf) {
184
    setup->fpf = fpf;
185
}
186
187
static void set_fail_tolerance(setup_t *setup, double fail_rate) {
188
    setup->tolerance = fail_rate;
189
}
190
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
191
static void request_uncompressable_data(setup_t *setup, size_t uc) {
192
    setup->uc = uc;
193
}
1 by Suren A. Chilingaryan
Initial release
194
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
195
static int callback(setup_t *s, size_t result, void *buffer);
196
1 by Suren A. Chilingaryan
Initial release
197
static void *run(setup_t *setup) {
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
198
#ifdef USE_UFO_GENERATOR
1 by Suren A. Chilingaryan
Initial release
199
    GError *error = NULL;
200
    UfoGraph *graph = NULL;
201
    /* If you want to use system-wide installed filters: 
202
     * graph = ufo_graph_new(); */
203
204
    graph = g_object_new(UFO_TYPE_GRAPH,
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
205
# ifdef METABALLS_PATH
1 by Suren A. Chilingaryan
Initial release
206
            "paths", METABALLS_PATH,
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
207
# endif /* METABALLS_PATH */
1 by Suren A. Chilingaryan
Initial release
208
            NULL);
209
210
//    printf("%lu %lu %lu %lu\n", setup->width, setup->height, setup->iters, setup->width * setup->height * setup->iters * sizeof(float));
211
    UfoFilter *metaballs = ufo_graph_get_filter(graph, "metaballs", &error);
212
    handle_error(error);
213
    g_object_set(G_OBJECT(metaballs),
214
            "width", setup->width,
215
            "height", setup->height,
216
            "num-balls", 1,
217
            "num-iterations", setup->iters,
218
            "frames-per-second", setup->fps,
219
            NULL);
220
221
    UfoFilter *writer = ufo_graph_get_filter(graph, "pipeoutput", &error);
222
    handle_error(error);
223
    g_object_set(G_OBJECT(writer),
224
            "pipe-name", fifo_name,
225
            NULL);
226
227
    ufo_filter_connect_to(metaballs, writer, &error);
228
    handle_error(error);
229
230
    setup->run_started = 1;
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
231
1 by Suren A. Chilingaryan
Initial release
232
    ufo_graph_run(graph, &error);
233
    handle_error(error);
3 by Suren A. Chilingaryan
getopt support
234
235
    g_thread_exit(NULL);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
236
#else /* USE_UFO_GENERATOR */
237
    size_t i;
238
    struct timeval tv;
239
    size_t size = setup->width * setup->height * setup->bpp;
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
240
    size_t pos = 0, mult = setup->uc / size;
241
    char *buffer = malloc((mult + 1) * size);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
242
    double interval = 1000000. / setup->fps, nextus;
243
    ssize_t tmp;
244
    size_t nexts;
245
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
246
    g_assert(buffer);
247
    
248
    if (!mult) mult = 1;
249
250
# ifdef WRITE_RANDOM
251
    if (setup->uc) {
252
	printf("Generating %zu MB of randomness...\n", mult * size / 1024 / 1024);
253
	int rfd = open(WRITE_RANDOM, O_RDONLY);
254
	g_assert(rfd >= 0);
255
	read(rfd, buffer, mult * size);
256
	close(rfd);
257
    }
258
# endif /* WRITE_RANDOM */
259
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
260
    setup->run_started = 1;
261
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
262
# ifdef USE_FIFO
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
263
    int fd = open(fifo_name, O_WRONLY);
264
    g_assert(fd >= 0);
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
265
# endif /* USE_FIFO */
266
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
267
    gettimeofday(&tv, NULL); 
268
    nexts = tv.tv_sec;
269
    nextus = tv.tv_usec + interval;
270
    for (i = 0; i < setup->iters; i++) {
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
271
# ifdef USE_FIFO
272
	ssize_t res = write(fd, buffer + pos * size, size);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
273
	g_assert(res == size);
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
274
# else /* USE_FIFO */
275
	callback(setup, size, buffer + pos * size);
276
# endif /* USE_FIFO */
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
277
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
278
	if ((++pos) == mult) pos = 0;
279
	
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
280
	tmp = ((size_t)round(nextus)) / 1000000;
281
	nexts += tmp;
282
	nextus -= tmp * 1000000;
283
284
	gettimeofday(&tv, NULL);
285
	tmp = (nexts - tv.tv_sec)*1000000 + (nextus - tv.tv_usec);
286
	if (tmp > 10) usleep(tmp);
287
	
288
	nextus += interval;
289
    }
290
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
291
# ifdef USE_FIFO
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
292
    close(fd);
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
293
# endif /* USE_FIFO */
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
294
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
295
    free(buffer);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
296
#endif /* USE_UFO_GENERATOR */
1 by Suren A. Chilingaryan
Initial release
297
298
    return NULL;
299
}
300
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
301
static int callback(setup_t *s, size_t result, void *buffer) {
302
    int err;
303
    struct timeval tv;
304
305
    fastwriter_t *fw = s->fw;
306
    fastwriter_stats_t stats;
307
308
    size_t duration, last_duration, expected;
309
    long delta;
310
3 by Suren A. Chilingaryan
getopt support
311
    gettimeofday(&tv, NULL);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
312
313
    if (!s->broken_frame) {
314
	err = fastwriter_push(fw, result, buffer);
315
    	if (err) {
316
    	    if (err == EWOULDBLOCK) {
3 by Suren A. Chilingaryan
getopt support
317
    		if (!s->tolerance) {
318
    		    if (s->verbose >= 0) printf("Lost frame...\n");
319
    		    exit(1);
320
    		}
321
    		
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
322
		if (s->num_read) fastwriter_cancel(fw);
323
		s->broken_frame = 1;
324
    	    } else {
325
	    	if (err) printf("FastWriter returned error %i\n", err);
326
		g_assert(!err);
327
	    }
328
	}
329
    }
330
331
    s->num_read += result; 
332
333
    if (s->num_read < s->frame_size) return 0;
334
335
    s->num_read = 0;
336
337
    if (s->broken_frame) {
338
	s->lost++;
339
	s->broken_frame = 0;
340
    } else {
341
	err = fastwriter_commit(fw);
342
	s->frames++;
3 by Suren A. Chilingaryan
getopt support
343
344
	if ((s->fpf)&&((s->frames%s->fpf) == 0)) {
345
	    fastwriter_close(s->fw);
346
	    set_current_output(s, s->frames);
347
	    err = fastwriter_open(s->fw, s->current_output,  FASTWRITER_FLAGS_OVERWRITE);
348
	    if (err) {
349
		printf("FastWriter returned error %i\n", err);
350
		g_assert(!err);
351
	    }
352
353
	// reopen
354
    }
355
356
    }
357
    
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
358
    if (!s->tv_started.tv_sec) {
359
    	memcpy(&s->tv_started, &tv, sizeof(struct timeval));
360
    	if (s->tv_started.tv_usec >= (1000000 / s->fps)) 
361
    	    s->tv_started.tv_usec -= (1000000 / s->fps);
362
    	else {
363
    	    s->tv_started.tv_sec--;
364
    	    s->tv_started.tv_usec += 1000000 - (1000000 / s->fps);
365
    	}
366
    	memcpy(&s->tv_last_written, &s->tv_started, sizeof(struct timeval));
367
    }
368
369
    fastwriter_get_stats(fw, &stats);
370
    if (stats.buffer_used > s->buf_max) s->buf_max = stats.buffer_used;
371
372
    if ((tv.tv_sec - s->tv_last_written.tv_sec) >= WRITE_INTERVAL) {
3 by Suren A. Chilingaryan
getopt support
373
	if ((s->tolerance > 0)&&(s->tolerance < 100)) {
374
	    double lost = (100. * s->lost / (s->lost + s->frames));
375
	    double last_lost = (100. * (s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames));
376
	    if ((lost > s->tolerance)||(last_lost > s->tolerance)) {
377
		if (s->verbose >= 0)
378
		    printf("Lost %.2lf%% (%lu) frames, total: %.2lf%% (%lu)\n", last_lost, s->lost - s->last_lost, lost, s->lost);
379
		exit(1);
380
	    }
381
	}
382
	
383
	if (s->verbose >= 0) {
384
	    last_duration = (tv.tv_sec - s->tv_last_written.tv_sec) * 1000000 + (tv.tv_usec - s->tv_last_written.tv_usec);
385
	    printf("Lost  %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*(s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames), s->lost - s->last_lost, s->lost + s->frames - (s->last_lost + s->last_frames), 1. * s->frame_size * (s->frames - s->last_frames) / 1024 / 1024 / 1024, 1000000. * s->frame_size * (s->frames - s->last_frames) / last_duration / 1024 / 1024, 100.*s->buf_max/stats.buffer_size);
386
	}
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
387
388
	if (((++s->writeouts)%WRITE_SUMMARY)==0) {
389
	    duration = (tv.tv_sec - s->tv_started.tv_sec) * 1000000 + (tv.tv_usec - s->tv_started.tv_usec);
390
	    expected = (tv.tv_sec - s->tv_started.tv_sec) * s->fps + round(1.*(tv.tv_usec - s->tv_started.tv_usec)*s->fps/1000000);
391
	    delta = expected - s->lost - s->frames;
392
    	    if ((delta > DELTA_TOLERANCE)||(delta < -DELTA_TOLERANCE))
393
    		printf(" *** Unexpected frame rate: %.2lf (%lu), delta: %li (%lu, %lu)\n", 1000000. * (s->frames + s->lost) / duration, s->fps, delta, s->lost + s->frames, expected); 
394
    		
3 by Suren A. Chilingaryan
getopt support
395
    	    if (s->verbose >= 0) {
396
		printf("Total %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100. * s->lost / (s->lost + s->frames), s->lost, s->lost + s->frames, 1. * s->frames * s->frame_size / 1024 / 1024 / 1024, 1000000. * s->frames * s->frame_size / duration / 1024 / 1024,  100.*stats.buffer_max / stats.buffer_size);
397
	    }
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
398
	}
399
	
400
	s->buf_max = 0;
401
	memcpy(&s->tv_last_written, &tv, sizeof(struct timeval));
402
	s->last_frames = s->frames;
403
	s->last_lost = s->lost;
404
    }
405
    
406
    return 0;
407
}
1 by Suren A. Chilingaryan
Initial release
408
409
3 by Suren A. Chilingaryan
getopt support
410
int main(int argc, char* const argv[])
1 by Suren A. Chilingaryan
Initial release
411
{
412
    int err;
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
413
414
#ifdef USE_FIFO
1 by Suren A. Chilingaryan
Initial release
415
    GError *gerr;
416
    GThread *thr;
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
417
#endif /* USE_FIFO */
418
1 by Suren A. Chilingaryan
Initial release
419
    setup_t setup;
3 by Suren A. Chilingaryan
getopt support
420
421
    unsigned char c;
422
    const char *sptr;
1 by Suren A. Chilingaryan
Initial release
423
    const char *out = "/dev/null";
3 by Suren A. Chilingaryan
getopt support
424
    double mpix = 0;
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
425
    size_t width = 1024;
426
    size_t height = 768;
1 by Suren A. Chilingaryan
Initial release
427
    size_t speed = 850;
3 by Suren A. Chilingaryan
getopt support
428
    size_t size = 0;
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
429
    size_t uc = 0;
3 by Suren A. Chilingaryan
getopt support
430
    size_t run_time = 0;
431
    size_t iters = 0x7FFFFFFF;
432
    size_t fw_buffer = 0;
433
    double fail_rate = 100.;
434
    size_t fpf = 0;
435
    int quiet = 0;
436
    
1 by Suren A. Chilingaryan
Initial release
437
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
438
    fastwriter_stats_t stats;
439
440
    g_thread_init(NULL);
441
442
#ifdef USE_UFO_GENERATOR
1 by Suren A. Chilingaryan
Initial release
443
    g_type_init();
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
444
#endif /* USE_UFO_GENERATOR */
1 by Suren A. Chilingaryan
Initial release
445
3 by Suren A. Chilingaryan
getopt support
446
447
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
448
    while ((c = getopt(argc, argv, "hqo:s:u:t:r:n:g:f:m:b:")) != (unsigned char)-1) {
3 by Suren A. Chilingaryan
getopt support
449
	switch (c) {
450
	 case OPT_OUTPUT:
451
	    out = optarg;
452
	    break;
453
	 case OPT_BUFFER:
454
            fw_buffer = atol(optarg);
455
	    break;
456
         case OPT_SIZE:
457
            size = atol(optarg);
458
	    break;
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
459
	 case OPT_UC:
460
	    uc = atol(optarg);
461
	    break;
3 by Suren A. Chilingaryan
getopt support
462
         case OPT_TIME:
463
            run_time = atol(optarg);
464
	    break;
465
         case OPT_FRAMES:
466
            iters = atol(optarg);
467
	    break;
468
         case OPT_RATE:
469
            speed = atoi(optarg);
470
            break;
471
         case OPT_GEOMETRY:
472
            sptr = strchr(optarg, 'x');
473
            if (sptr) {
474
        	width = atol(optarg);
475
        	height = atol(sptr + 1);
476
            } else {
477
        	mpix = atof(optarg);
478
            }
479
            break;
480
         case OPT_FPF:
481
            fpf = atol(optarg);
482
            break;
483
         case OPT_MISSING:
484
            fail_rate = atof(optarg);
485
            break;
486
        case OPT_QUIET:
487
    	    quiet = 1;
488
	    break;
489
         case OPT_HELP:
490
	    Usage(argc, argv, NULL);
491
     }
1 by Suren A. Chilingaryan
Initial release
492
    }
493
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
494
#ifdef USE_FIFO
1 by Suren A. Chilingaryan
Initial release
495
    unlink(fifo_name);
496
    g_assert(!mkfifo(fifo_name, S_IWUSR | S_IRUSR));
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
497
#endif /* USE_FIFO */
1 by Suren A. Chilingaryan
Initial release
498
3 by Suren A. Chilingaryan
getopt support
499
500
    memset(&setup, 0, sizeof(setup_t));
501
502
    if (quiet) set_verbosity(&setup, -1);
503
    set_output(&setup, out);
504
    
505
    if (mpix) set_pixels(&setup, mpix * 1000000);
506
    else set_dim(&setup, width, height);
507
508
    set_speed(&setup, speed * 1024 * 1024);
509
510
    if (size) set_size(&setup, size * 1024 * 1024 * 1024);
511
    else if (run_time) set_time(&setup, run_time);
512
    else set_iters(&setup, iters);
513
    
514
    set_fail_tolerance(&setup, fail_rate);
515
    set_frames_per_file(&setup, fpf);
516
14 by Suren A. Chilingaryan
Generate random data to check way too clever controllers
517
    request_uncompressable_data(&setup, uc * 1024 * 1024);
3 by Suren A. Chilingaryan
getopt support
518
519
    setup.fw = fastwriter_init(setup.fs, FASTWRITER_FLAGS_OVERWRITE);
520
    g_assert(setup.fw);
521
522
    if (fw_buffer) 
523
	fastwriter_set_buffer_size(setup.fw, fw_buffer * 1024 * 1024);
524
    else
525
	fastwriter_set_buffer_size(setup.fw, FASTWRITER_BUFFER_MAX);
526
    
527
    err = fastwriter_open(setup.fw, setup.current_output,  FASTWRITER_FLAGS_OVERWRITE);
1 by Suren A. Chilingaryan
Initial release
528
    if (err) printf("FastWriter returned error %i\n", err);
529
    g_assert(!err);
530
3 by Suren A. Chilingaryan
getopt support
531
532
    fastwriter_get_stats(setup.fw, &stats);
533
    if (!quiet)
534
	printf("*** Writing to %s, rate: %lu, data: %lu MB/s, buffer: %lu MB\n", out, setup.fps, speed, stats.buffer_size/1024/1024);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
535
536
    void *buffer = malloc(setup.frame_size);
1 by Suren A. Chilingaryan
Initial release
537
    g_assert(buffer);
538
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
539
#ifdef USE_FIFO
1 by Suren A. Chilingaryan
Initial release
540
    thr = g_thread_create((GThreadFunc)run, &setup, 1, &gerr);
541
    g_assert(thr);
542
543
    while (!setup.run_started);
544
545
    int fd = open(fifo_name, O_RDONLY);
546
    g_assert(fd);
547
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
548
    ssize_t result = read(fd, buffer, setup.frame_size);
1 by Suren A. Chilingaryan
Initial release
549
550
    while (result > 0) {
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
551
	callback(&setup, result, buffer);
552
        result = read(fd, buffer, setup.frame_size - setup.num_read);
1 by Suren A. Chilingaryan
Initial release
553
    }
554
4 by Suren A. Chilingaryan
Fix handling of size argument
555
    if (!quiet)
556
	printf("Wrote %lu GB\n", setup.frame_size * setup.frames / 1024 / 1024 / 1024);
1 by Suren A. Chilingaryan
Initial release
557
558
    g_thread_join(thr);
559
560
    close(fd);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
561
#else /* USE_FIFO */
562
    run(&setup);
563
#endif /* USE_FIFO */
1 by Suren A. Chilingaryan
Initial release
564
565
    free(buffer);
3 by Suren A. Chilingaryan
getopt support
566
    fastwriter_close(setup.fw);
567
    fastwriter_destroy(setup.fw);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
568
569
#ifdef USE_FIFO
1 by Suren A. Chilingaryan
Initial release
570
    unlink(fifo_name);
2 by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided
571
#endif /* USE_FIFO */
1 by Suren A. Chilingaryan
Initial release
572
573
    return 0;
574
}