Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /* WARNING:  This file was automatically generated!
  2.  * Original: ./src/thread/generic/SDL_syssem.c
  3.  */
  4. /*
  5.     SDL - Simple DirectMedia Layer
  6.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  7.  
  8.     This library is free software; you can redistribute it and/or
  9.     modify it under the terms of the GNU Library General Public
  10.     License as published by the Free Software Foundation; either
  11.     version 2 of the License, or (at your option) any later version.
  12.  
  13.     This library is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.     Library General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU Library General Public
  19.     License along with this library; if not, write to the Free
  20.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21.  
  22.     Sam Lantinga
  23.     slouken@devolution.com
  24. */
  25.  
  26.  
  27. /* An implementation of semaphores using mutexes and condition variables */
  28.  
  29. #include <stdlib.h>
  30.  
  31. #include "SDL_error.h"
  32. #include "SDL_timer.h"
  33. #include "SDL_thread.h"
  34. #include "SDL_systhread_c.h"
  35.  
  36.  
  37. #ifdef DISABLE_THREADS
  38.  
  39. SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
  40. {
  41.         SDL_SetError("SDL not configured with thread support");
  42.         return (SDL_sem *)0;
  43. }
  44.  
  45. void SDL_DestroySemaphore(SDL_sem *sem)
  46. {
  47.         return;
  48. }
  49.  
  50. int SDL_SemTryWait(SDL_sem *sem)
  51. {
  52.         SDL_SetError("SDL not configured with thread support");
  53.         return -1;
  54. }
  55.  
  56. int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
  57. {
  58.         SDL_SetError("SDL not configured with thread support");
  59.         return -1;
  60. }
  61.  
  62. int SDL_SemWait(SDL_sem *sem)
  63. {
  64.         SDL_SetError("SDL not configured with thread support");
  65.         return -1;
  66. }
  67.  
  68. Uint32 SDL_SemValue(SDL_sem *sem)
  69. {
  70.         return 0;
  71. }
  72.  
  73. int SDL_SemPost(SDL_sem *sem)
  74. {
  75.         SDL_SetError("SDL not configured with thread support");
  76.         return -1;
  77. }
  78.  
  79. #else
  80.  
  81. struct SDL_semaphore
  82. {
  83.         Uint32 count;
  84.         Uint32 waiters_count;
  85.         SDL_mutex *count_lock;
  86.         SDL_cond *count_nonzero;
  87. };
  88.  
  89. SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
  90. {
  91.         SDL_sem *sem;
  92.  
  93.         sem = (SDL_sem *)malloc(sizeof(*sem));
  94.         if ( ! sem ) {
  95.                 SDL_OutOfMemory();
  96.                 return(0);
  97.         }
  98.         sem->count = initial_value;
  99.         sem->waiters_count = 0;
  100.  
  101.         sem->count_lock = SDL_CreateMutex();
  102.         sem->count_nonzero = SDL_CreateCond();
  103.         if ( ! sem->count_lock || ! sem->count_nonzero ) {
  104.                 SDL_DestroySemaphore(sem);
  105.                 return(0);
  106.         }
  107.  
  108.         return(sem);
  109. }
  110.  
  111. /* WARNING:
  112.    You cannot call this function when another thread is using the semaphore.
  113. */
  114. void SDL_DestroySemaphore(SDL_sem *sem)
  115. {
  116.         if ( sem ) {
  117.                 sem->count = 0xFFFFFFFF;
  118.                 while ( sem->waiters_count > 0) {
  119.                         SDL_CondSignal(sem->count_nonzero);
  120.                         SDL_Delay(10);
  121.                 }
  122.                 SDL_DestroyCond(sem->count_nonzero);
  123.                 SDL_mutexP(sem->count_lock);
  124.                 SDL_mutexV(sem->count_lock);
  125.                 SDL_DestroyMutex(sem->count_lock);
  126.                 free(sem);
  127.         }
  128. }
  129.  
  130. int SDL_SemTryWait(SDL_sem *sem)
  131. {
  132.         int retval;
  133.  
  134.         if ( ! sem ) {
  135.                 SDL_SetError("Passed a NULL semaphore");
  136.                 return -1;
  137.         }
  138.  
  139.         retval = SDL_MUTEX_TIMEDOUT;
  140.         SDL_LockMutex(sem->count_lock);
  141.         if ( sem->count > 0 ) {
  142.                 --sem->count;
  143.                 retval = 0;
  144.         }
  145.         SDL_UnlockMutex(sem->count_lock);
  146.  
  147.         return retval;
  148. }
  149.  
  150. int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
  151. {
  152.         int retval;
  153.  
  154.         if ( ! sem ) {
  155.                 SDL_SetError("Passed a NULL semaphore");
  156.                 return -1;
  157.         }
  158.  
  159.         /* A timeout of 0 is an easy case */
  160.         if ( timeout == 0 ) {
  161.                 return SDL_SemTryWait(sem);
  162.         }
  163.  
  164.         SDL_LockMutex(sem->count_lock);
  165.         ++sem->waiters_count;
  166.         retval = 0;
  167.         while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
  168.                 retval = SDL_CondWaitTimeout(sem->count_nonzero,
  169.                                              sem->count_lock, timeout);
  170.         }
  171.         --sem->waiters_count;
  172.         --sem->count;
  173.         SDL_UnlockMutex(sem->count_lock);
  174.  
  175.         return retval;
  176. }
  177.  
  178. int SDL_SemWait(SDL_sem *sem)
  179. {
  180.         return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
  181. }
  182.  
  183. Uint32 SDL_SemValue(SDL_sem *sem)
  184. {
  185.         Uint32 value;
  186.        
  187.         value = 0;
  188.         if ( sem ) {
  189.                 SDL_LockMutex(sem->count_lock);
  190.                 value = sem->count;
  191.                 SDL_UnlockMutex(sem->count_lock);
  192.         }
  193.         return value;
  194. }
  195.  
  196. int SDL_SemPost(SDL_sem *sem)
  197. {
  198.         if ( ! sem ) {
  199.                 SDL_SetError("Passed a NULL semaphore");
  200.                 return -1;
  201.         }
  202.  
  203.         SDL_LockMutex(sem->count_lock);
  204.         if ( sem->waiters_count > 0 ) {
  205.                 SDL_CondSignal(sem->count_nonzero);
  206.         }
  207.         ++sem->count;
  208.         SDL_UnlockMutex(sem->count_lock);
  209.  
  210.         return 0;
  211. }
  212.  
  213. #endif /* DISABLE_THREADS */
  214.