#include "dada_hdu.h"
#include "multilog.h"
#include "ascii_header.h"
#include "futils.h"
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void usage()
{
fprintf (stdout,
"dada_write_block_test [options]\n"
" -H filename ascii header information in file\n"
" -g gigabytes number of gigabytes to write\n");
}
static char* default_header =
"OBS_ID dada_write_block_test.0001\n"
"OBS_OFFSET 100\n"
"FILE_SIZE 1073741824\n"
"FILE_NUMBER 3\n";
int main (int argc, char **argv)
{
dada_hdu_t* hdu = 0;
multilog_t* log;
uint64_t bytes_to_write = (uint64_t)(1024 * 1024) * (uint64_t)(534 * 5);
char* header = default_header;
char* header_buf = 0;
unsigned header_strlen = 0;
uint64_t header_size = 0;
char* header_file = 0;
char* data = 0;
char verbose = 0;
float gigabytes = 0.0;
float one_gigabyte = 1024.0 * 1024.0 * 1024.0;
int arg = 0;
while ((arg=getopt(argc,argv,"g:hH:v")) != -1) {
switch (arg) {
case 'g':
gigabytes = atof (optarg);
bytes_to_write = (uint64_t) (gigabytes * one_gigabyte);
break;
case 'H':
header_file = optarg;
break;
case 'v':
verbose=1;
break;
case 'h':
default:
usage ();
return 0;
}
}
log = multilog_open ("dada_write_block_test", 0);
multilog_add (log, stderr);
hdu = dada_hdu_create (log);
if (dada_hdu_connect (hdu) < 0)
return EXIT_FAILURE;
if (dada_hdu_lock_write (hdu) < 0)
return EXIT_FAILURE;
header_strlen = strlen(header);
header_size = ipcbuf_get_bufsz (hdu->header_block);
multilog (log, LOG_INFO, "header block size = %"PRIu64"\n", header_size);
header_buf = ipcbuf_get_next_write (hdu->header_block);
if (!header_buf)
{
multilog (log, LOG_ERR, "Could not get next header block\n");
return EXIT_FAILURE;
}
if (header_file)
{
multilog (log, LOG_INFO, "reading header file\n");
if (fileread (header_file, header_buf, header_size) < 0) {
multilog (log, LOG_ERR, "Could not read header from %s\n", header_file);
return EXIT_FAILURE;
}
}
else {
header_strlen = strlen(header);
memcpy (header_buf, header, header_strlen);
memset (header_buf + header_strlen, '\0', header_size - header_strlen);
}
if (verbose)
multilog (log, LOG_INFO, "setting HDR_SIZE=%"PRIu64"\n", header_size);
if (ascii_header_set (header_buf, "HDR_SIZE", "%"PRIu64"", header_size) < 0) {
multilog (log, LOG_ERR, "Could not write HDR_SIZE to header\n");
return -1;
}
if (verbose)
multilog (log, LOG_INFO, "marking header filled\n");
if (ipcbuf_mark_filled (hdu->header_block, header_size) < 0) {
multilog (log, LOG_ERR, "Could not mark filled header block\n");
return EXIT_FAILURE;
}
uint64_t bufsz = ipcbuf_get_bufsz ((ipcbuf_t *)hdu->data_block);
if (verbose)
multilog (log, LOG_INFO, "data block bufsz=%"PRIu64"\n", bufsz);
double nwrites = (double) bytes_to_write / (double) bufsz;
fprintf (stderr, "Writing %"PRIu64" bytes to data block in blocks of %"PRIu64" (%lf writes)\n", bytes_to_write, bufsz, nwrites);
data = (char*) malloc (bufsz);
assert (data != 0);
const unsigned opened = 5;
unsigned i;
uint64_t bytess[opened];
uint64_t index = 0;
uint64_t interleave_num = 1024;
uint64_t n_opened = 0;
uint64_t n_closed = 0;
uint64_t bufid;
char * buf;
while (bytes_to_write)
{
for (i=0; i<opened; i++)
{
bytess[i] = bufsz;
if (bytess[i] > bytes_to_write)
bytess[i] = bytes_to_write;
if (bytess[i] > 0)
{
multilog (log, LOG_INFO, "ipcio_open_block_write() opened=%lu closed=%lu\n", n_opened, n_closed);
buf = ipcio_open_block_write (hdu->data_block, &bufid);
n_opened++;
if (buf)
{
if (verbose)
multilog (log, LOG_INFO, "buf=%p id=%"PRIu64"\n", buf, bufid);
uint64_t uint64_count = bufsz / sizeof(uint64_t);
unsigned k = 0;
uint64_t j = 0;
char * ptr = 0;
unsigned char ch;
if (verbose)
multilog (log, LOG_INFO, "writing %lu 64-bit uints\n", uint64_count);
for (j=0; j<uint64_count; j++)
{
ptr = buf + j * sizeof(uint64_t);
for (k = 0; k < 8; k++ )
{
ch = (index >> ((k & 7) << 3)) & 0xFF;
ptr[8 - k - 1] = ch;
}
index++;
if (index % interleave_num == 0)
{
if (verbose)
fprintf(stderr, "increment %"PRIu64" -> ", index);
index += interleave_num;
if (verbose)
fprintf(stderr, "%"PRIu64"\n", index);
}
}
bytes_to_write -= bytess[i];
}
else
bytess[i] = 0;
}
}
for (i=0; i<opened; i++)
{
if (bytess[i] > 0)
{
multilog (log, LOG_INFO, "ipcio_close_block_write(%"PRIu64")\n", bytess[i]);
ipcio_close_block_write (hdu->data_block, bytess[i]);
n_closed++;
}
}
}
if (dada_hdu_unlock_write (hdu) < 0)
return EXIT_FAILURE;
if (dada_hdu_disconnect (hdu) < 0)
return EXIT_FAILURE;
dada_hdu_destroy (hdu);
return EXIT_SUCCESS;
}