Browse Source

implement pthread support for tests

Steffen Jaeckel 8 years ago
parent
commit
d6a77f5d6d
1 changed files with 70 additions and 12 deletions
  1. 70 12
      tests/test.c

+ 70 - 12
tests/test.c

@@ -6,10 +6,12 @@
 
 
 #define LTC_TEST_FN(f)  { f, #f }
 #define LTC_TEST_FN(f)  { f, #f }
 
 
-static const struct {
+typedef struct {
    int (*fn)(void);
    int (*fn)(void);
    const char* name;
    const char* name;
-} test_functions[] =
+} test_function;
+
+static const test_function test_functions[] =
 {
 {
       LTC_TEST_FN(store_test),
       LTC_TEST_FN(store_test),
       LTC_TEST_FN(rotate_test),
       LTC_TEST_FN(rotate_test),
@@ -33,6 +35,7 @@ static const struct {
       LTC_TEST_FN(prng_test),
       LTC_TEST_FN(prng_test),
 };
 };
 
 
+
 #if defined(_WIN32)
 #if defined(_WIN32)
   #include <windows.h> /* GetSystemTimeAsFileTime */
   #include <windows.h> /* GetSystemTimeAsFileTime */
 #else
 #else
@@ -63,6 +66,28 @@ static ulong64 epoch_usec(void)
 #endif
 #endif
 }
 }
 
 
+#ifdef LTC_PTHREAD
+typedef struct
+{
+   pthread_t thread_id;
+   const test_function* t;
+   int err;
+   ulong64 ts;
+} thread_info;
+
+static void *run(void *arg)
+{
+   thread_info *tinfo = arg;
+   ulong64 ts;
+
+   ts = epoch_usec();
+   tinfo->err = tinfo->t->fn();
+   tinfo->ts = epoch_usec() - ts;
+
+   return arg;
+}
+#endif
+
 
 
 /*
 /*
  * unregister ciphers, hashes & prngs
  * unregister ciphers, hashes & prngs
@@ -241,11 +266,14 @@ static void register_algs(void)
 
 
 int main(int argc, char **argv)
 int main(int argc, char **argv)
 {
 {
+#ifdef LTC_PTHREAD
+   thread_info *tinfo, *res;
+#endif
    int x, pass = 0, fail = 0, nop = 0;
    int x, pass = 0, fail = 0, nop = 0;
    size_t fn_len, i, dots;
    size_t fn_len, i, dots;
    char *single_test = NULL;
    char *single_test = NULL;
    ulong64 ts;
    ulong64 ts;
-   long delta, dur = 0;
+   long delta, dur, real = 0;
    register_algs();
    register_algs();
 
 
    printf("build == %s\n%s\n", GIT_VERSION, crypt_build_settings);
    printf("build == %s\n%s\n", GIT_VERSION, crypt_build_settings);
@@ -266,10 +294,28 @@ int main(int argc, char **argv)
 #endif
 #endif
    printf("MP_DIGIT_BIT = %d\n", MP_DIGIT_BIT);
    printf("MP_DIGIT_BIT = %d\n", MP_DIGIT_BIT);
 
 
+
+#ifdef LTC_PTHREAD
+   tinfo = XCALLOC(sizeof(test_functions)/sizeof(test_functions[0]), sizeof(thread_info));
+   if (tinfo == NULL) {
+      printf("\n\nFAILURE: XCALLOC\n");
+      return EXIT_FAILURE;
+   }
+#endif
+
    fn_len = 0;
    fn_len = 0;
-   for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
+   for (i = 0; i < sizeof(test_functions) / sizeof(test_functions[0]); ++i) {
       size_t len = strlen(test_functions[i].name);
       size_t len = strlen(test_functions[i].name);
       if (fn_len < len) fn_len = len;
       if (fn_len < len) fn_len = len;
+
+#ifdef LTC_PTHREAD
+      tinfo[i].t = &test_functions[i];
+      x = pthread_create(&tinfo[i].thread_id, NULL, run, &tinfo[i]);
+      if (x != 0)  {
+         printf("\n\nFAILURE: pthread_create\n");
+         return EXIT_FAILURE;
+      }
+#endif
    }
    }
 
 
    fn_len = fn_len + (4 - (fn_len % 4));
    fn_len = fn_len + (4 - (fn_len % 4));
@@ -277,6 +323,7 @@ int main(int argc, char **argv)
    /* single test name from commandline */
    /* single test name from commandline */
    if (argc > 1) single_test = argv[1];
    if (argc > 1) single_test = argv[1];
 
 
+   dur = epoch_usec();
    for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
    for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
       if (single_test && strcmp(test_functions[i].name, single_test)) {
       if (single_test && strcmp(test_functions[i].name, single_test)) {
         continue;
         continue;
@@ -287,10 +334,21 @@ int main(int argc, char **argv)
       while(dots--) printf(".");
       while(dots--) printf(".");
       fflush(stdout);
       fflush(stdout);
 
 
+#ifdef LTC_PTHREAD
+      x = pthread_join(tinfo[i].thread_id, (void**)&res);
+      if (x != 0){
+         printf("\n\nFAILURE: pthread_join\n");
+         return EXIT_FAILURE;
+      }
+      ts = res->ts;
+      x = res->err;
+#else
       ts = epoch_usec();
       ts = epoch_usec();
       x = test_functions[i].fn();
       x = test_functions[i].fn();
       delta = (long)(epoch_usec() - ts);
       delta = (long)(epoch_usec() - ts);
       dur += delta;
       dur += delta;
+#endif
+      real += dur;
 
 
       if (x == CRYPT_OK) {
       if (x == CRYPT_OK) {
          printf("passed %10.3fms", (double)(delta)/1000);
          printf("passed %10.3fms", (double)(delta)/1000);
@@ -305,15 +363,15 @@ int main(int argc, char **argv)
          fail++;
          fail++;
       }
       }
    }
    }
+   dur = epoch_usec() - dur;
 
 
-   if (fail > 0 || fail+pass+nop == 0) {
-      printf("\n\nFAILURE: passed=%d failed=%d nop=%d duration=%.1fsec\n", pass, fail, nop, (double)(dur)/(1000*1000));
-      return EXIT_FAILURE;
-   }
-   else {
-      printf("\n\nSUCCESS: passed=%d failed=%d nop=%d duration=%.1fsec\n", pass, fail, nop, (double)(dur)/(1000*1000));
-      return EXIT_SUCCESS;
-   }
+#ifdef LTC_PTHREAD
+   XFREE(tinfo);
+#endif
+
+   x = (fail > 0 || fail+pass+nop == 0) ? EXIT_FAILURE : EXIT_SUCCESS;
+   printf("\n\n%s: passed=%d failed=%d nop=%d duration=%.1fsec real=%.1fsec\n", x ? "FAILURE" : "SUCCESS", pass, fail, nop, (double)(dur)/(1000*1000), (double)(real)/(1000*1000));
+   return x;
 }
 }
 
 
 /* $Source$ */
 /* $Source$ */