root/maint/gnulib/lib/pthread-cond.c

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

DEFINITIONS

This source file includes following definitions.
  1. pthread_condattr_init
  2. pthread_condattr_destroy
  3. pthread_cond_init
  4. pthread_cond_wait
  5. pthread_cond_timedwait
  6. pthread_cond_signal
  7. pthread_cond_broadcast
  8. pthread_cond_destroy
  9. pthread_cond_init
  10. pthread_cond_wait
  11. pthread_cond_timedwait
  12. pthread_cond_signal
  13. pthread_cond_broadcast
  14. pthread_cond_destroy

   1 /* POSIX condition variables.
   2    Copyright (C) 2010-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file 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 Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Paul Eggert, 2010, and Bruno Haible <bruno@clisp.org>, 2019.  */
  18 
  19 #include <config.h>
  20 
  21 /* Specification.  */
  22 #include <pthread.h>
  23 
  24 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
  25 # include "windows-thread.h"
  26 #else
  27 # include <errno.h>
  28 # include <limits.h>
  29 # include <sys/time.h>
  30 # include <time.h>
  31 #endif
  32 
  33 #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
  34 
  35 int
  36 pthread_condattr_init (pthread_condattr_t *attr)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38   *attr = 0;
  39   return 0;
  40 }
  41 
  42 int
  43 pthread_condattr_destroy (_GL_UNUSED pthread_condattr_t *attr)
     /* [previous][next][first][last][top][bottom][index][help] */
  44 {
  45   return 0;
  46 }
  47 
  48 #endif
  49 
  50 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
  51 /* Use Windows threads.  */
  52 
  53 int
  54 pthread_cond_init (pthread_cond_t *cond,
     /* [previous][next][first][last][top][bottom][index][help] */
  55                    _GL_UNUSED const pthread_condattr_t *attr)
  56 {
  57   return glwthread_cond_init (cond);
  58 }
  59 
  60 int
  61 pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63   return glwthread_cond_wait (cond, mutex,
  64                               (int (*) (void *)) pthread_mutex_lock,
  65                               (int (*) (void *)) pthread_mutex_unlock);
  66 }
  67 
  68 int
  69 pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
     /* [previous][next][first][last][top][bottom][index][help] */
  70                         const struct timespec *abstime)
  71 {
  72   return glwthread_cond_timedwait (cond, mutex,
  73                                    (int (*) (void *)) pthread_mutex_lock,
  74                                    (int (*) (void *)) pthread_mutex_unlock,
  75                                    abstime);
  76 }
  77 
  78 int
  79 pthread_cond_signal (pthread_cond_t *cond)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81   return glwthread_cond_signal (cond);
  82 }
  83 
  84 int
  85 pthread_cond_broadcast (pthread_cond_t *cond)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87   return glwthread_cond_broadcast (cond);
  88 }
  89 
  90 int
  91 pthread_cond_destroy (pthread_cond_t *cond)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   return glwthread_cond_destroy (cond);
  94 }
  95 
  96 #elif HAVE_PTHREAD_H
  97 /* Provide workarounds for POSIX threads.  */
  98 
  99 #else
 100 /* Provide a dummy implementation for single-threaded applications.  */
 101 
 102 int
 103 pthread_cond_init (_GL_UNUSED pthread_cond_t *cond,
     /* [previous][next][first][last][top][bottom][index][help] */
 104                    _GL_UNUSED const pthread_condattr_t *attr)
 105 {
 106   /* COND is never seriously used.  */
 107   return 0;
 108 }
 109 
 110 int
 111 pthread_cond_wait (_GL_UNUSED pthread_cond_t *cond,
     /* [previous][next][first][last][top][bottom][index][help] */
 112                    _GL_UNUSED pthread_mutex_t *mutex)
 113 {
 114   /* No other thread can signal this condition variable.
 115      Wait endlessly.  */
 116   for (;;)
 117     {
 118       struct timespec duration;
 119 
 120       duration.tv_sec = 86400;
 121       duration.tv_nsec = 0;
 122       nanosleep (&duration, NULL);
 123     }
 124 }
 125 
 126 int
 127 pthread_cond_timedwait (_GL_UNUSED pthread_cond_t *cond,
     /* [previous][next][first][last][top][bottom][index][help] */
 128                         _GL_UNUSED pthread_mutex_t *mutex,
 129                         const struct timespec *abstime)
 130 {
 131   /* No other thread can signal this condition variable.
 132      Wait until ABSTIME is reached.  */
 133   for (;;)
 134     {
 135       struct timeval currtime;
 136       unsigned long remaining;
 137       struct timespec duration;
 138 
 139       gettimeofday (&currtime, NULL);
 140 
 141       if (currtime.tv_sec > abstime->tv_sec)
 142         remaining = 0;
 143       else
 144         {
 145           unsigned long seconds = abstime->tv_sec - currtime.tv_sec;
 146           remaining = seconds * 1000000000;
 147           if (remaining / 1000000000 != seconds) /* overflow? */
 148             remaining = ULONG_MAX;
 149           else
 150             {
 151               long nanoseconds =
 152                 abstime->tv_nsec - currtime.tv_usec * 1000;
 153               if (nanoseconds >= 0)
 154                 {
 155                   remaining += nanoseconds;
 156                   if (remaining < nanoseconds) /* overflow? */
 157                     remaining = ULONG_MAX;
 158                 }
 159               else
 160                 {
 161                   if (remaining >= - nanoseconds)
 162                     remaining -= (- nanoseconds);
 163                   else
 164                     remaining = 0;
 165                 }
 166             }
 167         }
 168       if (remaining == 0)
 169         return ETIMEDOUT;
 170 
 171       /* Sleep up to REMAINING ns.  */
 172       duration.tv_sec = remaining / 1000000000;
 173       duration.tv_nsec = remaining % 1000000000;
 174       nanosleep (&duration, NULL);
 175     }
 176 }
 177 
 178 int
 179 pthread_cond_signal (_GL_UNUSED pthread_cond_t *cond)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181   /* No threads can currently be blocked on COND.  */
 182   return 0;
 183 }
 184 
 185 int
 186 pthread_cond_broadcast (_GL_UNUSED pthread_cond_t *cond)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188   /* No threads can currently be blocked on COND.  */
 189   return 0;
 190 }
 191 
 192 int
 193 pthread_cond_destroy (_GL_UNUSED pthread_cond_t *cond)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195   /* COND is never seriously used.  */
 196   return 0;
 197 }
 198 
 199 #endif

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