Add a basic create and join thread test case.
authorWerner Koch <wk@gnupg.org>
Thu, 10 May 2012 14:55:48 +0000 (16:55 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 10 May 2012 14:55:48 +0000 (16:55 +0200)
* tests/t-thread.c: New
* tests/t-support.h (opt_verbose):  New.
(fail_msg, info_msg): New.

tests/Makefile.am
tests/t-support.h
tests/t-thread.c [new file with mode: 0644]

index bd85ba5..39b0672 100644 (file)
@@ -28,7 +28,7 @@
 
 ## Process this file with automake to produce Makefile.in
 
-TESTS = t-mutex
+TESTS = t-mutex t-thread
 
 # We explicitly require POSIX.1-2001 so that pthread_rwlock_t is
 # available when build with c99.
index db4fb9c..a477e9f 100644 (file)
@@ -21,6 +21,9 @@
 #define DIM(v)              (sizeof(v)/sizeof((v)[0]))
 #endif
 
+static int opt_verbose;
+
+
 #define fail_if_err(err)                                       \
   do                                                           \
     {                                                          \
         }                                                      \
     }                                                          \
   while (0)
+
+#define fail_msg(text)                                          \
+  do                                                           \
+    {                                                          \
+      fprintf (stderr, "%s:%d: %s\n",                           \
+               __FILE__, __LINE__, text);                       \
+      exit (1);                                                 \
+    }                                                          \
+  while (0)
+
+#define info_msg(text)                          \
+  do                                            \
+    {                                           \
+      if (opt_verbose)                          \
+        fprintf (stderr, "%s\n", text);         \
+    }                                           \
+  while (0)
diff --git a/tests/t-thread.c b/tests/t-thread.c
new file mode 100644 (file)
index 0000000..38333a6
--- /dev/null
@@ -0,0 +1,163 @@
+/* t-thread.c
+ * Copyright 2012 g10 Code GmbH
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "t-support.h"
+
+
+static int counter;
+static npth_mutex_t counter_mutex;
+static int thread_twoone_ready;
+
+static void *
+thread_one (void *arg)
+{
+  int rc, i;
+
+  info_msg ("thread-one started");
+  npth_usleep (10);  /* Give the other thread some time to start.  */
+  for (i=0; i < 10; i++)
+    {
+      /* We would not need the mutex here, but we use it to allow the
+         system to switch to another thread.  */
+      rc = npth_mutex_lock (&counter_mutex);
+      fail_if_err (rc);
+
+      counter++;
+
+      rc = npth_mutex_unlock (&counter_mutex);
+      fail_if_err (rc);
+    }
+  info_msg ("thread-one terminated");
+
+  return (void*)4711;
+}
+
+
+static void *
+thread_twoone (void *arg)
+{
+  int rc, i;
+
+  npth_setname_np (npth_self (), "thread-twoone");
+  info_msg ("thread-twoone started");
+
+  rc = npth_detach (npth_self ());
+  fail_if_err (rc);
+
+  while (counter < 100)
+    {
+      npth_usleep (1000);
+      counter++;
+    }
+  info_msg ("thread-twoone terminated");
+  thread_twoone_ready = 1;
+
+  return NULL;
+}
+
+
+static void *
+thread_two (void *arg)
+{
+  int rc, i;
+
+  info_msg ("thread-two started");
+
+  for (i=0; i < 10; i++)
+    {
+      rc = npth_mutex_lock (&counter_mutex);
+      fail_if_err (rc);
+
+      counter--;
+
+      if (i == 5)
+        {
+          npth_t tid;
+
+          info_msg ("creating thread-twoone");
+          rc = npth_create (&tid, NULL, thread_twoone, NULL);
+          fail_if_err (rc);
+          npth_usleep (10);  /* Give new thread some time to start.  */
+        }
+
+      rc = npth_mutex_unlock (&counter_mutex);
+      fail_if_err (rc);
+    }
+
+  info_msg ("busy waiting for thread twoone");
+  while (!thread_twoone_ready)
+    npth_sleep (0);
+
+  info_msg ("thread-two terminated");
+
+  return (void*)4722;
+}
+
+
+
+
+
+int
+main (int argc, char *argv[])
+{
+  int rc;
+  npth_attr_t tattr;
+  int state;
+  npth_t tid1, tid2;
+  void *retval;
+
+  if (argc >= 2 && !strcmp (argv[1], "--verbose"))
+    opt_verbose = 1;
+
+  rc = npth_init ();
+  fail_if_err (rc);
+
+  rc = npth_mutex_init (&counter_mutex, NULL);
+  fail_if_err (rc);
+
+  rc = npth_attr_init (&tattr);
+  fail_if_err (rc);
+  rc = npth_attr_getdetachstate (&tattr, &state);
+  fail_if_err (rc);
+  if ( state != NPTH_CREATE_JOINABLE )
+    fail_msg ("new tattr is not joinable");
+
+  info_msg ("creating thread-one");
+  rc = npth_create (&tid1, &tattr, thread_one, NULL);
+  fail_if_err (rc);
+  npth_setname_np (tid1, "thread-one");
+
+  info_msg ("creating thread-two");
+  rc = npth_create (&tid2, &tattr, thread_two, NULL);
+  fail_if_err (rc);
+  npth_setname_np (tid2, "thread-two");
+
+  rc = npth_attr_destroy (&tattr);
+  fail_if_err (rc);
+
+  info_msg ("waiting for thread-one to terminate");
+  rc = npth_join (tid1, &retval);
+  fail_if_err (rc);
+  if (retval != (void*)4711)
+    fail_msg ("thread-one returned an unexpected value");
+
+  info_msg ("waiting for thread-two to terminate");
+  rc = npth_join (tid2, &retval);
+  fail_if_err (rc);
+  if (retval != (void*)4722)
+    fail_msg ("thread-two returned an unexpected value");
+
+  if (counter != 100)
+    fail_msg ("counter value not as expected");
+
+  return 0;
+}