PageRenderTime 30ms CodeModel.GetById 16ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sdl-1.3/src/thread/nds/SDL_syssem.c

https://github.com/aichunyu/FFPlayer
C | 229 lines | 166 code | 37 blank | 26 comment | 17 complexity | 65715a4ade7f1f61a3843e87b2956868 MD5 | raw file
  1/*
  2  Simple DirectMedia Layer
  3  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
  4
  5  This software is provided 'as-is', without any express or implied
  6  warranty.  In no event will the authors be held liable for any damages
  7  arising from the use of this software.
  8
  9  Permission is granted to anyone to use this software for any purpose,
 10  including commercial applications, and to alter it and redistribute it
 11  freely, subject to the following restrictions:
 12
 13  1. The origin of this software must not be misrepresented; you must not
 14     claim that you wrote the original software. If you use this software
 15     in a product, an acknowledgment in the product documentation would be
 16     appreciated but is not required.
 17  2. Altered source versions must be plainly marked as such, and must not be
 18     misrepresented as being the original software.
 19  3. This notice may not be removed or altered from any source distribution.
 20*/
 21
 22#ifdef SAVE_RCSID
 23static char rcsid =
 24    "@(#) $Id: SDL_syssem.c,v 1.2 2001/04/26 16:50:18 hercules Exp $";
 25#endif
 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
 39SDL_sem *
 40SDL_CreateSemaphore(Uint32 initial_value)
 41{
 42    SDL_SetError("SDL not configured with thread support");
 43    return (SDL_sem *) 0;
 44}
 45
 46void
 47SDL_DestroySemaphore(SDL_sem * sem)
 48{
 49    return;
 50}
 51
 52int
 53SDL_SemTryWait(SDL_sem * sem)
 54{
 55    SDL_SetError("SDL not configured with thread support");
 56    return -1;
 57}
 58
 59int
 60SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
 61{
 62    SDL_SetError("SDL not configured with thread support");
 63    return -1;
 64}
 65
 66int
 67SDL_SemWait(SDL_sem * sem)
 68{
 69    SDL_SetError("SDL not configured with thread support");
 70    return -1;
 71}
 72
 73Uint32
 74SDL_SemValue(SDL_sem * sem)
 75{
 76    return 0;
 77}
 78
 79int
 80SDL_SemPost(SDL_sem * sem)
 81{
 82    SDL_SetError("SDL not configured with thread support");
 83    return -1;
 84}
 85
 86#else
 87
 88struct SDL_semaphore
 89{
 90    Uint32 count;
 91    Uint32 waiters_count;
 92    SDL_mutex *count_lock;
 93    SDL_cond *count_nonzero;
 94};
 95
 96SDL_sem *
 97SDL_CreateSemaphore(Uint32 initial_value)
 98{
 99    SDL_sem *sem;
100
101    sem = (SDL_sem *) malloc(sizeof(*sem));
102    if (!sem) {
103        SDL_OutOfMemory();
104        return (0);
105    }
106    sem->count = initial_value;
107    sem->waiters_count = 0;
108
109    sem->count_lock = SDL_CreateMutex();
110    sem->count_nonzero = SDL_CreateCond();
111    if (!sem->count_lock || !sem->count_nonzero) {
112        SDL_DestroySemaphore(sem);
113        return (0);
114    }
115
116    return (sem);
117}
118
119/* WARNING:
120   You cannot call this function when another thread is using the semaphore.
121*/
122void
123SDL_DestroySemaphore(SDL_sem * sem)
124{
125    if (sem) {
126        sem->count = 0xFFFFFFFF;
127        while (sem->waiters_count > 0) {
128            SDL_CondSignal(sem->count_nonzero);
129            SDL_Delay(10);
130        }
131        SDL_DestroyCond(sem->count_nonzero);
132        SDL_mutexP(sem->count_lock);
133        SDL_mutexV(sem->count_lock);
134        SDL_DestroyMutex(sem->count_lock);
135        free(sem);
136    }
137}
138
139int
140SDL_SemTryWait(SDL_sem * sem)
141{
142    int retval;
143
144    if (!sem) {
145        SDL_SetError("Passed a NULL semaphore");
146        return -1;
147    }
148
149    retval = SDL_MUTEX_TIMEDOUT;
150    SDL_LockMutex(sem->count_lock);
151    if (sem->count > 0) {
152        --sem->count;
153        retval = 0;
154    }
155    SDL_UnlockMutex(sem->count_lock);
156
157    return retval;
158}
159
160int
161SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
162{
163    int retval;
164
165    if (!sem) {
166        SDL_SetError("Passed a NULL semaphore");
167        return -1;
168    }
169
170    /* A timeout of 0 is an easy case */
171    if (timeout == 0) {
172        return SDL_SemTryWait(sem);
173    }
174
175    SDL_LockMutex(sem->count_lock);
176    ++sem->waiters_count;
177    retval = 0;
178    while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
179        retval = SDL_CondWaitTimeout(sem->count_nonzero,
180                                     sem->count_lock, timeout);
181    }
182    --sem->waiters_count;
183    --sem->count;
184    SDL_UnlockMutex(sem->count_lock);
185
186    return retval;
187}
188
189int
190SDL_SemWait(SDL_sem * sem)
191{
192    return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
193}
194
195Uint32
196SDL_SemValue(SDL_sem * sem)
197{
198    Uint32 value;
199
200    value = 0;
201    if (sem) {
202        SDL_LockMutex(sem->count_lock);
203        value = sem->count;
204        SDL_UnlockMutex(sem->count_lock);
205    }
206    return value;
207}
208
209int
210SDL_SemPost(SDL_sem * sem)
211{
212    if (!sem) {
213        SDL_SetError("Passed a NULL semaphore");
214        return -1;
215    }
216
217    SDL_LockMutex(sem->count_lock);
218    if (sem->waiters_count > 0) {
219        SDL_CondSignal(sem->count_nonzero);
220    }
221    ++sem->count;
222    SDL_UnlockMutex(sem->count_lock);
223
224    return 0;
225}
226
227#endif /* DISABLE_THREADS */
228
229/* vi: set ts=4 sw=4 expandtab: */