Beispiel #1
0
int free_systimer(systimer_t * timer)
{
   int err ;

   err = free_iochannel(timer) ;
   if (err) goto ONERR;

   return 0 ;
ONERR:
   TRACEEXITFREE_ERRLOG(err);
   return err ;
}
Beispiel #2
0
int free_logbuffer(logbuffer_t * logbuf)
{
   int err;

   logbuf->addr = 0;
   logbuf->size = 0;
   logbuf->logsize = 0;

   if (  logbuf->io == iochannel_STDOUT
         || logbuf->io == iochannel_STDERR) {
      logbuf->io = iochannel_FREE;
   } else {
      err = free_iochannel(&logbuf->io);
      if (err) goto ONERR;
   }

   return 0;
ONERR:
   TRACEEXITFREE_ERRLOG(err);
   return err;
}
Beispiel #3
0
static int test_rwpartial(directory_t* tmpdir)
{
   iothread_t  iothr = iothread_FREE;
   file_t      file = file_FREE;
   memblock_t  writebuf = memblock_FREE;
   memblock_t  readbuf  = memblock_FREE;
   iotask_t    iotask_buffer;
   iotask_t*   iotask = &iotask_buffer;
   eventcount_t counter = eventcount_INIT;

   // prepare0
   TEST(0 == init_iothread(&iothr));
   // alloc buffer
   TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &readbuf));
   TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &writebuf));
   for (size_t val = 0; val < writebuf.size/sizeof(uint32_t); ++val) {
      ((uint32_t*)writebuf.addr)[val] = (uint32_t) val;
   }
   memset(readbuf.addr, 0, readbuf.size);

   for (int ispos = 0; ispos <= 1; ++ispos) {

      // TEST insertiotask_iothread: (writep,write) && syscall writes less than writebuf.size
      TEST(0 == initcreate_file(&file, "testpartial", tmpdir))
      if (ispos) {
         initwritep_iotask(iotask, io_file(file), writebuf.size, writebuf.addr, 0, &counter);
      } else {
         initwrite_iotask(iotask, io_file(file), writebuf.size, writebuf.addr, &counter);
      }
      // test
      s_iothread_errtimer_count = 0;
      init_testerrortimer(&s_iothread_errtimer, 2/*trigger partial io*/, 1);
      insertiotask_iothread(&iothr, 1, &iotask);
      // wait for writer ready
      wait_eventcount(&counter,0);
      // check iotask
      TEST(iotask->iolist_next == 0);
      TEST(iotask->bytesrw    == writebuf.size);
      TEST(iotask->state      == iostate_OK);
      TEST(iotask->op         == ioop_WRITE);
      TEST(iotask->ioc        == io_file(file));
      TEST(iotask->offset     == (ispos ? 0 : -1));
      TEST(iotask->bufaddr    == writebuf.addr);
      TEST(iotask->bufsize    == writebuf.size);
      TEST(iotask->readycount == &counter);
      // check 32 partial writes (1+32)
      TEST(32 == s_iothread_errtimer_count);
      // reset
      TEST(0 == free_file(&file));
      free_testerrortimer(&s_iothread_errtimer);

      // TEST insertiotask_iothread: (readp, read) && syscall reads less than writebuf.size
      TEST(0 == init_file(&file, "testpartial", accessmode_READ, tmpdir));
      if (ispos) {
         initreadp_iotask(iotask, io_file(file), readbuf.size, readbuf.addr, 0, &counter);
      } else {
         initread_iotask(iotask, io_file(file), readbuf.size, readbuf.addr, &counter);
      }
      // test
      s_iothread_errtimer_count = 0;
      init_testerrortimer(&s_iothread_errtimer, 2/*trigger partial io*/, 1);
      insertiotask_iothread(&iothr, 1, &iotask);
      // wait for reader ready
      wait_eventcount(&counter,0);
      // check iotask.ioop[0]
      TEST(iotask->iolist_next == 0);
      TEST(iotask->bytesrw    == writebuf.size);
      TEST(iotask->state      == iostate_OK);
      TEST(iotask->op         == ioop_READ);
      TEST(iotask->ioc        == io_file(file));
      TEST(iotask->offset     == (ispos ? 0 : -1));
      TEST(iotask->bufaddr    == readbuf.addr);
      TEST(iotask->bufsize    == readbuf.size);
      TEST(iotask->readycount == &counter);
      // check content of readbuf
      for (size_t val = 0; val < readbuf.size/sizeof(uint32_t); ++val) {
         TEST(val == ((uint32_t*)readbuf.addr)[val]);
      }
      // check 32 partial writes (1+32)
      TEST(32 == s_iothread_errtimer_count);
      // reset
      memset(readbuf.addr, 0, readbuf.size);
      TEST(0 == free_file(&file));
      TEST(0 == removefile_directory(tmpdir, "testpartial"));
      free_testerrortimer(&s_iothread_errtimer);
   }

   // reset
   TEST(0 == free_iothread(&iothr));
   TEST(0 == free_eventcount(&counter));
   TEST(0 == free_iochannel(&file));
   TEST(0 == RELEASE_PAGECACHE(&writebuf));
   TEST(0 == RELEASE_PAGECACHE(&readbuf));

   return 0;
ONERR:
   free_iothread(&iothr);
   free_eventcount(&counter);
   free_iochannel(&file);
   RELEASE_PAGECACHE(&writebuf);
   RELEASE_PAGECACHE(&readbuf);
   removefile_directory(tmpdir, "testpartial");
   return EINVAL;
}
Beispiel #4
0
static int test_write(directory_t* tmpdir)
{
   iothread_t  iothr = iothread_FREE;
   file_t      file = file_FREE;
   memblock_t  mblock[10] = { memblock_FREE };
   memblock_t  readbuf = memblock_FREE;
   iotask_t    iotask_buffer[lengthof(mblock)];
   iotask_t*   iotask[lengthof(mblock)];
   eventcount_t counter = eventcount_INIT;

   // prepare0
   TEST(0 == init_iothread(&iothr));
   memset(iotask_buffer, 0, sizeof(iotask_buffer));
   for (unsigned i = 0; i < lengthof(iotask); ++i) {
      iotask[i] = &iotask_buffer[i];
   }
   // fill write buffer
   for (size_t i = 0, val = 0; i < lengthof(mblock); ++i) {
      TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &mblock[i]));
      for (size_t off = 0; off < mblock[i].size/sizeof(uint32_t); ++off, ++val) {
         ((uint32_t*)mblock[i].addr)[off] = (uint32_t) val;
      }
   }
   // alloc read buffer
   TEST(0 == ALLOC_PAGECACHE(pagesize_1MB, &readbuf));
   memset(readbuf.addr, 0, readbuf.size);

   // TEST insertiotask_iothread: writep (forward)
   static_assert((lengthof(iotask)-1) % 3 == 0, "full range 1..lengthof(iotask)");
   for (unsigned nrio = 1; nrio <= lengthof(iotask); nrio += 3) {
      // prepare
      TEST(0 == initcreate_file(&file, "testwrite", tmpdir));
      for (size_t i = 0; i < nrio; ++i) {
         initwritep_iotask(iotask[i], io_file(file), mblock[i].size, mblock[i].addr, (off_t) (i*mblock[0].size), &counter);
      }
      // test
      insertiotask_iothread(&iothr, (uint8_t) nrio, &iotask[0]);
      // check
      for (unsigned i = 0; i < nrio; ++i) {
         // wait for ready counter
         while (iostate_QUEUED == read_atomicint(&iotask[i]->state)) {
            wait_eventcount(&counter,0);
         }
         // check iotask
         TEST(0 == compare_iotask(iotask[i], 0, mblock[i].size, iostate_OK, ioop_WRITE, io_file(file),
                     (off_t) (i*mblock[0].size), mblock[i].addr, mblock[i].size, &counter));
         // check written bytes
         TEST((int)readbuf.size == pread(io_file(file), readbuf.addr, readbuf.size, iotask[i]->offset));
         for (size_t vi = 0, val = (size_t)iotask[i]->offset/sizeof(uint32_t); vi < readbuf.size/sizeof(uint32_t); ++vi, ++val) {
            TEST(val == ((uint32_t*)readbuf.addr)[vi]);
         }
         // reset
         iotask[i]->bytesrw = 0;
      }
      // check file position (offset) not changed
      TEST(0 == lseek(io_file(file), 0, SEEK_CUR));
      // reset
      TEST(0 == free_iochannel(&file));
      TEST(0 == removefile_directory(tmpdir, "testwrite"));
      counter.nrevents = 0;
   }

   // TEST insertiotask_iothread: writep (backward)
   static_assert((lengthof(iotask)-1) % 3 == 0, "full range 1..lengthof(iotask)");
   for (unsigned nrio = 1; nrio <= lengthof(iotask); nrio += 3) {
      // prepare
      TEST(0 == initcreate_file(&file, "testwrite", tmpdir));
      for (unsigned i = 0; i < nrio; ++i) {
         initwritep_iotask(iotask[i], io_file(file), mblock[i].size, mblock[i].addr, (off_t)((nrio-1-i)*mblock[0].size), &counter);
      }
      // test
      insertiotask_iothread(&iothr, (uint8_t) nrio, &iotask[0]);
      // check
      for (unsigned i = 0; i < nrio; ++i) {
         // wait for ready counter
         while (iostate_QUEUED == read_atomicint(&iotask[i]->state)) {
            wait_eventcount(&counter,0);
         }
         // check iotask
         TEST(0 == compare_iotask(iotask[i], 0, mblock[i].size, iostate_OK, ioop_WRITE, io_file(file),
                     (off_t) ((nrio-1-i)*mblock[0].size), mblock[i].addr, mblock[i].size, &counter));
         // check written bytes
         TEST((int)readbuf.size == pread(io_file(file), readbuf.addr, readbuf.size, iotask[i]->offset));
         for (size_t vi = 0, val = i*mblock[0].size/sizeof(uint32_t); vi < readbuf.size/sizeof(uint32_t); ++vi, ++val) {
            TEST(val == ((uint32_t*)readbuf.addr)[vi]);
         }
         // reset
         iotask[i]->bytesrw = 0;
      }
      // check file position (offset) not changed
      TEST(0 == lseek(io_file(file), 0, SEEK_CUR));
      // reset
      TEST(0 == free_iochannel(&file));
      TEST(0 == removefile_directory(tmpdir, "testwrite"));
      counter.nrevents = 0;
   }

   // TEST insertiotask_iothread: write
   // prepare
   TEST(0 == initcreate_file(&file, "testwrite", tmpdir));
   for (unsigned i = 0; i < lengthof(iotask); ++i) {
      initwrite_iotask(iotask[i], io_file(file), mblock[i].size, mblock[i].addr, 0);
   }
   // test
   insertiotask_iothread(&iothr, lengthof(iotask), &iotask[0]);
   // check
   for (unsigned i = 0; i < lengthof(iotask); ++i) {
      // wait for ready counter
      for (int w = 0; w < 500000; ++w) {
         if (iostate_QUEUED != read_atomicint(&iotask[i]->state)) break;
         yield_thread();
      }
      // check iotask
      TEST(0 == compare_iotask(iotask[i], 0, mblock[i].size, iostate_OK, ioop_WRITE, io_file(file),
                  -1, mblock[i].addr, mblock[i].size, 0));
      // check written bytes
      TEST((int)readbuf.size == pread(io_file(file), readbuf.addr, readbuf.size, (off_t)(i*mblock[0].size)));
      for (size_t vi = 0, val = (i*mblock[0].size)/sizeof(uint32_t); vi < readbuf.size/sizeof(uint32_t); ++vi, ++val) {
         TEST(val == ((uint32_t*)readbuf.addr)[vi]);
      }
      // reset
      iotask[i]->bytesrw = 0;
   }
   // check file position (offset) changed
   TEST((off_t)(lengthof(mblock)*mblock[0].size) == lseek(io_file(file), 0, SEEK_CUR));

   // reset
   TEST(0 == free_iochannel(&file));
   TEST(0 == removefile_directory(tmpdir, "testwrite"));

   // reset0
   TEST(0 == free_iothread(&iothr));
   TEST(0 == free_eventcount(&counter));
   for (unsigned i = 0; i < lengthof(mblock); ++i) {
      TEST(0 == RELEASE_PAGECACHE(&mblock[i]));
   }
   TEST(0 == RELEASE_PAGECACHE(&readbuf));

   return 0;
ONERR:
   free_iothread(&iothr);
   free_eventcount(&counter);
   free_iochannel(&file);
   for (unsigned i = 0; i < lengthof(mblock); ++i) {
      RELEASE_PAGECACHE(&mblock[i]);
   }
   RELEASE_PAGECACHE(&readbuf);
   removefile_directory(tmpdir, "testwrite");
   return EINVAL;
}