Exemple #1
0
ram_reply_t ramtest_join(ramtest_test_t *test_arg)
{
   size_t i = 0;
   ram_reply_t myreply = RAM_REPLY_OK;
   size_t unused = 0;

   RAM_FAIL_NOTNULL(test_arg);

   RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
         "[0] i am waiting for my threads to finish...\n"));
   for (i = 0; i < test_arg->ramtestt_params.ramtestp_threadcount; ++i)
   {
      ram_reply_t e = RAM_REPLY_INSANE;

      RAM_FAIL_TRAP(ramthread_join(&e, test_arg->ramtestt_threads[i]));
      if (RAM_REPLY_OK != e)
      {
         RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
               "[0] thread %zu replied with an unexpected failure (%d).\n",
               i + 1, (int)e));
         /* if i haven't yet recorded an error as my reply, do so now. this
          * ensures that the primary symptom is recorded and not any echoes
          * of the problem. */
         RAM_FAIL_TRAP(ram_fail_accumulate(&myreply, e));
      }
   }

   return myreply;
}
Exemple #2
0
ram_reply_t ramtest_test(const ramtest_params_t *params_arg)
{
   ram_reply_t e = RAM_REPLY_INSANE;
   ramtest_test_t test = {0};
   size_t unused = 0;

   RAM_FAIL_NOTNULL(params_arg);

   RAM_FAIL_TRAP(ramtest_describe(stderr, params_arg));

   /* if a dry run has been specified, i'll quit now. */
   if (params_arg->ramtestp_dryrun)
      return RAM_REPLY_OK;

   RAM_FAIL_TRAP(ramtest_inittest(&test, params_arg));

   e = ramtest_test2(&test);
   RAM_FAIL_TRAP(ram_fail_accumulate(&e, ramtest_fintest(&test)));

   if (RAM_REPLY_OK == e)
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
            "[0] the test succeeded.\n"));
      return RAM_REPLY_OK;
   }
   else
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
            "[0] the test failed (reply code %d).\n", e));
      RAM_FAIL_TRAP(e);
      return RAM_REPLY_INSANE;
   }
}
Exemple #3
0
ram_reply_t ramtest_start(ramtest_test_t *test_arg)
{
   size_t i = 0;
   size_t unused = 0;

   RAM_FAIL_NOTNULL(test_arg);

   for (i = 0; i < test_arg->ramtestt_params.ramtestp_threadcount; ++i)
   {
      ramtest_start_t *start = NULL;
      const size_t threadid = i + 1;

      RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
            "[0] starting thread %zu...\n", threadid));
      /* i'm the sole producer of this memory; *ramtest_start()* is the sole
       * consumer. */
      start = (ramtest_start_t *)calloc(sizeof(*start), 1);
      RAM_FAIL_EXPECT(RAM_REPLY_RESOURCEFAIL, NULL != start);
      start->ramtests_test = test_arg;
      start->ramtests_threadidx = i;
      RAM_FAIL_TRAP(ramthread_mkthread(&test_arg->ramtestt_threads[i],
            &ramtest_thread, start));
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
            "[0] started thread %zu.\n", threadid));
   }

   return RAM_REPLY_OK;
}
Exemple #4
0
ram_reply_t ramtest_test2(ramtest_test_t *test_arg)
{
   size_t unused = 0;

   RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
         "[0] beginning test...\n"));

   RAM_FAIL_TRAP(ramtest_start(test_arg));
   RAM_FAIL_TRAP(ramtest_join(test_arg));

   return RAM_REPLY_OK;
}
Exemple #5
0
ram_reply_t runtest2(const ramtest_params_t *params_arg,
      extra_t *extra_arg)
{
   ramtest_params_t testparams = {0};
   size_t unused = 0;

   testparams = *params_arg;
   /* i am responsible for policing the minimum and maximum allocation
    * size here. */
   if (testparams.ramtestp_minsize < sizeof(void *) ||
         testparams.ramtestp_maxsize < sizeof(void *))
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
            "you cannot specify a size smaller than %zu bytes.\n",
            sizeof(void *)));
      return RAM_REPLY_INPUTFAIL;
   }
   /* TODO: shouldn't this test be moved into the framework? */
   if (testparams.ramtestp_minsize > testparams.ramtestp_maxsize)
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
            "please specify a minimum size (%zu bytes) that is smaller than "
            "or equal to the maximum (%zu bytes).\n",
            testparams.ramtestp_minsize, testparams.ramtestp_maxsize));
      return RAM_REPLY_INPUTFAIL;
   }
   /* TODO: how do i determine the maximum allocation size ahead of time? */
   testparams.ramtestp_extra = extra_arg;
   testparams.ramtestp_acquire = &acquire;
   testparams.ramtestp_release = &release;
   testparams.ramtestp_query = &query;
   testparams.ramtestp_flush = &flush;
   testparams.ramtestp_check = &check;

   RAM_FAIL_TRAP(ramtest_test(&testparams));

   return RAM_REPLY_OK;
}
Exemple #6
0
ram_reply_t ramtest_thread(void *arg)
{
   ramtest_start_t *start = (ramtest_start_t *)arg;
   ramtest_test_t *test = NULL;
   size_t threadidx = 0, threadid = 0;
   ram_reply_t e = RAM_REPLY_INSANE;
   size_t unused = 0;

   RAM_FAIL_NOTNULL(arg);

   test = start->ramtests_test;
   threadidx = start->ramtests_threadidx;
   /* i'm the sole consumer of this memory; *ramtest_start()* is the sole
    * producer. */
   free(start);
   threadid = threadidx + 1;
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr, "[%zu] testing...\n",
         threadid));
   e = ramtest_thread2(test, threadidx);
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr, "[%zu] finished.\n",
         threadid));

   return e;
}
Exemple #7
0
int main(int argc, char *argv[])
{
   ram_reply_t e = RAM_REPLY_INSANE;
   size_t unused = 0;

   e = main2(argc, argv);
   if (RAM_REPLY_OK != e)
      RAM_FAIL_TRAP(ramtest_fprintf(&unused,stderr, "fail (%d).", e));
   if (RAM_REPLY_INPUTFAIL == e)
   {
      usage(e, argc, argv);
      ram_fail_panic("unreachable code.");
      return RAM_REPLY_INSANE;
   }
   else
      return e;
}
Exemple #8
0
ram_reply_t ramtest_describe(FILE *out_arg,
      const ramtest_params_t *params_arg)
{
   size_t unused = 0;

   RAM_FAIL_NOTNULL(out_arg);
   RAM_FAIL_NOTNULL(params_arg);

   if (params_arg->ramtestp_dryrun)
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "you have specified the following test:\n\n"));
   }
   else
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "i will run the following test:\n\n"));
   }
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
         "%zu allocation(s) (and corresponding deallocations).\n",
         params_arg->ramtestp_alloccount));
   if (1 == params_arg->ramtestp_threadcount)
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "this test will not be parallelized.\n"));
   }
   else
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "%zu parallel operation(s) allowed.\n",
            params_arg->ramtestp_threadcount));
   }
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
         "%d%% of the allocations will be managed by malloc() "
         "and free().\n", params_arg->ramtestp_mallocchance));
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
         "allocations will not be smaller than %zu bytes.\n",
         params_arg->ramtestp_minsize));
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
         "allocations will not be larger than %zu bytes.\n",
         params_arg->ramtestp_maxsize));
   if (params_arg->ramtestp_userngseed)
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "the random number generator will use seed %u.\n",
            params_arg->ramtestp_rngseed));
   }
   else
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "the random number generator will use a randomly "
            "selected seed.\n"));
   }
#if RAM_WANT_OVERCONFIDENT
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
         "warning: this is an overconfident build, so the results cannot "
         "be trusted. rebuild with RAMOPT_UNSUPPORTED_OVERCONFIDENT "
         "#define'd as 0 if you wish to have reliable results.\n");
#endif
   if (params_arg->ramtestp_dryrun)
   {
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg,
            "\nto run this test, omit the --dry-run option.\n"));
   }
   else
      RAM_FAIL_TRAP(ramtest_fprintf(&unused, out_arg, "-----\n"));

   return RAM_REPLY_OK;
}
Exemple #9
0
ram_reply_t ramtest_inittest2(ramtest_test_t *test_arg,
      const ramtest_params_t *params_arg)
{
   size_t i = 0;
   size_t seqlen = 0;
   size_t maxthreads = 0;
   size_t unused = 0;

   RAM_FAIL_NOTNULL(params_arg);
   RAM_FAIL_NOTZERO(params_arg->ramtestp_alloccount);
   RAM_FAIL_EXPECT(RAM_REPLY_RANGEFAIL, params_arg->ramtestp_minsize > 0);
   RAM_FAIL_EXPECT(RAM_REPLY_RANGEFAIL,
         params_arg->ramtestp_minsize <= params_arg->ramtestp_maxsize);
   RAM_FAIL_EXPECT(RAM_REPLY_RANGEFAIL, params_arg->ramtestp_mallocchance >= 0);
   RAM_FAIL_EXPECT(RAM_REPLY_RANGEFAIL, params_arg->ramtestp_mallocchance <= 100);
   RAM_FAIL_NOTNULL(params_arg->ramtestp_acquire);
   RAM_FAIL_NOTNULL(params_arg->ramtestp_release);
   RAM_FAIL_NOTNULL(params_arg->ramtestp_query);
   /* *params_arg->ramtestp_flush* is allowed to be NULL. */
   RAM_FAIL_NOTNULL(params_arg->ramtestp_check);

   RAM_FAIL_TRAP(ramtest_maxthreadcount(&maxthreads));
   RAM_FAIL_EXPECT(RAM_REPLY_DISALLOWED,
         params_arg->ramtestp_threadcount <= maxthreads);

   test_arg->ramtestt_params = *params_arg;
   if (0 == test_arg->ramtestt_params.ramtestp_threadcount)
   {
      RAM_FAIL_TRAP(ramtest_defaultthreadcount(
            &test_arg->ramtestt_params.ramtestp_threadcount));
   }
   test_arg->ramtestt_records =
         calloc(test_arg->ramtestt_params.ramtestp_alloccount,
         sizeof(*test_arg->ramtestt_records));
   RAM_FAIL_EXPECT(RAM_REPLY_RESOURCEFAIL,
         NULL != test_arg->ramtestt_records);
   test_arg->ramtestt_threads =
         calloc(test_arg->ramtestt_params.ramtestp_threadcount,
         sizeof(*test_arg->ramtestt_threads));
   RAM_FAIL_EXPECT(RAM_REPLY_RESOURCEFAIL,
         NULL != test_arg->ramtestt_threads);
   seqlen = test_arg->ramtestt_params.ramtestp_alloccount * 2;
   test_arg->ramtestt_sequence = calloc(seqlen,
         sizeof(*test_arg->ramtestt_sequence));
   RAM_FAIL_EXPECT(RAM_REPLY_RESOURCEFAIL,
         NULL != test_arg->ramtestt_sequence);

   RAM_FAIL_TRAP(rammtx_mkmutex(&test_arg->ramtestt_mtx));
   for (i = 0; i < test_arg->ramtestt_params.ramtestp_alloccount; ++i)
   {
      RAM_FAIL_TRAP(rammtx_mkmutex(
            &test_arg->ramtestt_records[i].ramtestar_mtx));
   }
   /* the sequence array must contain two copies of each index into
    * *test_arg->ramtestt_records*. the first represents an allocation.
    * the second, a deallocation. */
   for (i = 0; i < seqlen; ++i)
      test_arg->ramtestt_sequence[i] = (i / 2);
   /* i shuffle the sequence array to ensure a randomized order of
    * operations. */
   RAM_FAIL_TRAP(ramtest_shuffle(test_arg->ramtestt_sequence,
         sizeof(test_arg->ramtestt_sequence[0]), seqlen));

   if (!test_arg->ramtestt_params.ramtestp_userngseed)
      test_arg->ramtestt_params.ramtestp_rngseed = (unsigned int)time(NULL);
   srand(test_arg->ramtestt_params.ramtestp_rngseed);
   RAM_FAIL_TRAP(ramtest_fprintf(&unused, stderr,
         "[0] i seeded the random generator with the value %u.\n",
         test_arg->ramtestt_params.ramtestp_rngseed));

   test_arg->ramtestt_nextrec = 0;

   return RAM_REPLY_OK;
}