root/maint/gnulib/tests/test-cond.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gl_cond_define_initialized
  2. test_cond
  3. get_ts
  4. timedcond_routine
  5. test_timedcond
  6. main
  7. main

   1 /* Test of condition variables in multithreaded situations.
   2    Copyright (C) 2008-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 #include <config.h>
  18 
  19 #if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
  20 
  21 /* Which tests to perform.
  22    Uncomment some of these, to verify that all tests crash if no locking
  23    is enabled.  */
  24 #define DO_TEST_COND 1
  25 #define DO_TEST_TIMEDCOND 1
  26 
  27 
  28 /* Whether to help the scheduler through explicit yield().
  29    Uncomment this to see if the operating system has a fair scheduler.  */
  30 #define EXPLICIT_YIELD 1
  31 
  32 /* Whether to print debugging messages.  */
  33 #define ENABLE_DEBUGGING 0
  34 
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <string.h>
  38 #include <sys/time.h>
  39 #include <unistd.h>
  40 
  41 #include "glthread/cond.h"
  42 #include "glthread/lock.h"
  43 #include "glthread/thread.h"
  44 #include "glthread/yield.h"
  45 
  46 #if ENABLE_DEBUGGING
  47 # define dbgprintf printf
  48 #else
  49 # define dbgprintf if (0) printf
  50 #endif
  51 
  52 #if EXPLICIT_YIELD
  53 # define yield() gl_thread_yield ()
  54 #else
  55 # define yield()
  56 #endif
  57 
  58 
  59 /*
  60  * Condition check
  61  */
  62 static int cond_value = 0;
  63 gl_cond_define_initialized(static, condtest)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 gl_lock_define_initialized(static, lockcond)
  65 
  66 static void *
  67 cond_routine (void *arg)
  68 {
  69   gl_lock_lock (lockcond);
  70   while (!cond_value)
  71     {
  72       gl_cond_wait (condtest, lockcond);
  73     }
  74   gl_lock_unlock (lockcond);
  75 
  76   cond_value = 2;
  77 
  78   return NULL;
  79 }
  80 
  81 static void
  82 test_cond ()
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84   int remain = 2;
  85   gl_thread_t thread;
  86 
  87   cond_value = 0;
  88 
  89   thread = gl_thread_create (cond_routine, NULL);
  90   do
  91     {
  92       yield ();
  93       remain = sleep (remain);
  94     }
  95   while (remain);
  96 
  97   /* signal condition */
  98   gl_lock_lock (lockcond);
  99   cond_value = 1;
 100   gl_cond_signal (condtest);
 101   gl_lock_unlock (lockcond);
 102 
 103   gl_thread_join (thread, NULL);
 104 
 105   if (cond_value != 2)
 106     abort ();
 107 }
 108 
 109 
 110 /*
 111  * Timed Condition check
 112  */
 113 static int cond_timeout;
 114 
 115 static void
 116 get_ts (struct timespec *ts)
     /* [previous][next][first][last][top][bottom][index][help] */
 117 {
 118   struct timeval now;
 119 
 120   gettimeofday (&now, NULL);
 121 
 122   ts->tv_sec = now.tv_sec + 1;
 123   ts->tv_nsec = now.tv_usec * 1000;
 124 }
 125 
 126 static void *
 127 timedcond_routine (void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129   int ret;
 130   struct timespec ts;
 131 
 132   gl_lock_lock (lockcond);
 133   while (!cond_value)
 134     {
 135       get_ts (&ts);
 136       ret = glthread_cond_timedwait (&condtest, &lockcond, &ts);
 137       if (ret == ETIMEDOUT)
 138         cond_timeout = 1;
 139     }
 140   gl_lock_unlock (lockcond);
 141 
 142   return NULL;
 143 }
 144 
 145 static void
 146 test_timedcond (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148   int remain = 2;
 149   gl_thread_t thread;
 150 
 151   cond_value = cond_timeout = 0;
 152 
 153   thread = gl_thread_create (timedcond_routine, NULL);
 154   do
 155     {
 156       yield ();
 157       remain = sleep (remain);
 158     }
 159   while (remain);
 160 
 161   /* signal condition */
 162   gl_lock_lock (lockcond);
 163   cond_value = 1;
 164   gl_cond_signal (condtest);
 165   gl_lock_unlock (lockcond);
 166 
 167   gl_thread_join (thread, NULL);
 168 
 169   if (!cond_timeout)
 170     abort ();
 171 }
 172 
 173 int
 174 main ()
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176 #if DO_TEST_COND
 177   printf ("Starting test_cond ..."); fflush (stdout);
 178   test_cond ();
 179   printf (" OK\n"); fflush (stdout);
 180 #endif
 181 #if DO_TEST_TIMEDCOND
 182   printf ("Starting test_timedcond ..."); fflush (stdout);
 183   test_timedcond ();
 184   printf (" OK\n"); fflush (stdout);
 185 #endif
 186 
 187   return 0;
 188 }
 189 
 190 #else
 191 
 192 /* No multithreading available.  */
 193 
 194 #include <stdio.h>
 195 
 196 int
 197 main ()
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199   fputs ("Skipping test: multithreading not enabled\n", stderr);
 200   return 77;
 201 }
 202 
 203 #endif

/* [previous][next][first][last][top][bottom][index][help] */