src/thread/linux/SDL_syscond.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. SDL_CreateCond
  2. SDL_DestroyCond
  3. SDL_CondSignal
  4. SDL_CondBroadcast
  5. SDL_CondWaitTimeout
  6. SDL_CondWait

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_syscond.c,v 1.1.2.8 2001/03/21 17:19:56 hercules Exp $";
  26 #endif
  27 
  28 #ifdef linux
  29 /* Look to see if glibc is available, and if so, what version */
  30 #include <features.h>
  31 
  32 #if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
  33 #warning Working around a bug in glibc 2.0 pthreads
  34 #undef SDL_USE_PTHREADS
  35 /* The bug is actually a problem where threads are suspended, but don't
  36    wake up when the thread manager sends them a signal.  This is a problem
  37    with thread creation too, but it happens less often. :-/
  38    We avoid this by using System V IPC for mutexes.
  39  */
  40 #endif /* glibc 2.0 */
  41 #endif /* linux */
  42 
  43 #ifdef SDL_USE_PTHREADS
  44 
  45 #include <sys/time.h>
  46 #include <unistd.h>
  47 #include <errno.h>
  48 #include <stdlib.h>
  49 #include <pthread.h>
  50 
  51 #include "SDL_error.h"
  52 #include "SDL_thread.h"
  53 #include "SDL_sysmutex_c.h"
  54 
  55 
  56 #if defined(PTHREAD_NO_RECURSIVE_MUTEX) && !defined(__bsdi__)
  57 #error You need to use the generic condition variable implementation
  58 #endif
  59 
  60 struct SDL_cond
  61 {
  62         pthread_cond_t cond;
  63 };
  64 
  65 /* Create a condition variable */
  66 SDL_cond * SDL_CreateCond(void)
     /* [<][>][^][v][top][bottom][index][help] */
  67 {
  68         SDL_cond *cond;
  69 
  70         cond = (SDL_cond *) malloc(sizeof(SDL_cond));
  71         if ( cond ) {
  72                 if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
  73                         SDL_SetError("pthread_cond_init() failed");
  74                         free(cond);
  75                         cond = NULL;
  76                 }
  77         }
  78         return(cond);
  79 }
  80 
  81 /* Destroy a condition variable */
  82 void SDL_DestroyCond(SDL_cond *cond)
     /* [<][>][^][v][top][bottom][index][help] */
  83 {
  84         if ( cond ) {
  85                 pthread_cond_destroy(&cond->cond);
  86                 free(cond);
  87         }
  88 }
  89 
  90 /* Restart one of the threads that are waiting on the condition variable */
  91 int SDL_CondSignal(SDL_cond *cond)
     /* [<][>][^][v][top][bottom][index][help] */
  92 {
  93         int retval;
  94 
  95         if ( ! cond ) {
  96                 SDL_SetError("Passed a NULL condition variable");
  97                 return -1;
  98         }
  99 
 100         retval = 0;
 101         if ( pthread_cond_signal(&cond->cond) != 0 ) {
 102                 SDL_SetError("pthread_cond_signal() failed");
 103                 retval = -1;
 104         }
 105         return retval;
 106 }
 107 
 108 /* Restart all threads that are waiting on the condition variable */
 109 int SDL_CondBroadcast(SDL_cond *cond)
     /* [<][>][^][v][top][bottom][index][help] */
 110 {
 111         int retval;
 112 
 113         if ( ! cond ) {
 114                 SDL_SetError("Passed a NULL condition variable");
 115                 return -1;
 116         }
 117 
 118         retval = 0;
 119         if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
 120                 SDL_SetError("pthread_cond_broadcast() failed");
 121                 retval = -1;
 122         }
 123         return retval;
 124 }
 125 
 126 int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
     /* [<][>][^][v][top][bottom][index][help] */
 127 {
 128         int retval;
 129         struct timeval delta;
 130         struct timespec abstime;
 131 
 132         if ( ! cond ) {
 133                 SDL_SetError("Passed a NULL condition variable");
 134                 return -1;
 135         }
 136 
 137         gettimeofday(&delta, NULL);
 138 
 139         abstime.tv_sec = delta.tv_sec + (ms/1000);
 140         abstime.tv_nsec = (delta.tv_usec+(ms%1000)) * 1000;
 141         if ( abstime.tv_nsec > 1000000 ) {
 142           abstime.tv_sec += 1;
 143           abstime.tv_nsec -= 1000000;
 144         }
 145 
 146   tryagain:
 147         retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
 148         switch (retval) {
 149             case EINTR:
 150                 goto tryagain;
 151                 break;
 152             case ETIMEDOUT:
 153                 retval = SDL_MUTEX_TIMEDOUT;
 154                 break;
 155             case 0:
 156                 break;
 157             default:
 158                 SDL_SetError("pthread_cond_timedwait() failed");
 159                 retval = -1;
 160                 break;
 161         }
 162         return retval;
 163 }
 164 
 165 /* Wait on the condition variable, unlocking the provided mutex.
 166    The mutex must be locked before entering this function!
 167  */
 168 int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
     /* [<][>][^][v][top][bottom][index][help] */
 169 {
 170         int retval;
 171 
 172         if ( ! cond ) {
 173                 SDL_SetError("Passed a NULL condition variable");
 174                 return -1;
 175         }
 176 
 177         retval = 0;
 178         if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
 179                 SDL_SetError("pthread_cond_wait() failed");
 180                 retval = -1;
 181         }
 182         return retval;
 183 }
 184 
 185 #else /* Use semaphore implementation */
 186 
 187 #include "generic/SDL_syscond.c"
 188 
 189 #endif /* SDL_USE_PTHREADS */

/* [<][>][^][v][top][bottom][index][help] */