cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_syssem.c (3598B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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#include "../../SDL_internal.h"
     22
     23#if SDL_THREAD_WINDOWS
     24
     25/* Semaphore functions using the Win32 API */
     26
     27#include "../../core/windows/SDL_windows.h"
     28
     29#include "SDL_thread.h"
     30
     31struct SDL_semaphore
     32{
     33    HANDLE id;
     34    LONG count;
     35};
     36
     37
     38/* Create a semaphore */
     39SDL_sem *
     40SDL_CreateSemaphore(Uint32 initial_value)
     41{
     42    SDL_sem *sem;
     43
     44    /* Allocate sem memory */
     45    sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
     46    if (sem) {
     47        /* Create the semaphore, with max value 32K */
     48        sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
     49        sem->count = initial_value;
     50        if (!sem->id) {
     51            SDL_SetError("Couldn't create semaphore");
     52            SDL_free(sem);
     53            sem = NULL;
     54        }
     55    } else {
     56        SDL_OutOfMemory();
     57    }
     58    return (sem);
     59}
     60
     61/* Free the semaphore */
     62void
     63SDL_DestroySemaphore(SDL_sem * sem)
     64{
     65    if (sem) {
     66        if (sem->id) {
     67            CloseHandle(sem->id);
     68            sem->id = 0;
     69        }
     70        SDL_free(sem);
     71    }
     72}
     73
     74int
     75SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
     76{
     77    int retval;
     78    DWORD dwMilliseconds;
     79
     80    if (!sem) {
     81        return SDL_SetError("Passed a NULL sem");
     82    }
     83
     84    if (timeout == SDL_MUTEX_MAXWAIT) {
     85        dwMilliseconds = INFINITE;
     86    } else {
     87        dwMilliseconds = (DWORD) timeout;
     88    }
     89    switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
     90    case WAIT_OBJECT_0:
     91        InterlockedDecrement(&sem->count);
     92        retval = 0;
     93        break;
     94    case WAIT_TIMEOUT:
     95        retval = SDL_MUTEX_TIMEDOUT;
     96        break;
     97    default:
     98        retval = SDL_SetError("WaitForSingleObject() failed");
     99        break;
    100    }
    101    return retval;
    102}
    103
    104int
    105SDL_SemTryWait(SDL_sem * sem)
    106{
    107    return SDL_SemWaitTimeout(sem, 0);
    108}
    109
    110int
    111SDL_SemWait(SDL_sem * sem)
    112{
    113    return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
    114}
    115
    116/* Returns the current count of the semaphore */
    117Uint32
    118SDL_SemValue(SDL_sem * sem)
    119{
    120    if (!sem) {
    121        SDL_SetError("Passed a NULL sem");
    122        return 0;
    123    }
    124    return (Uint32)sem->count;
    125}
    126
    127int
    128SDL_SemPost(SDL_sem * sem)
    129{
    130    if (!sem) {
    131        return SDL_SetError("Passed a NULL sem");
    132    }
    133    /* Increase the counter in the first place, because
    134     * after a successful release the semaphore may
    135     * immediately get destroyed by another thread which
    136     * is waiting for this semaphore.
    137     */
    138    InterlockedIncrement(&sem->count);
    139    if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) {
    140        InterlockedDecrement(&sem->count);      /* restore */
    141        return SDL_SetError("ReleaseSemaphore() failed");
    142    }
    143    return 0;
    144}
    145
    146#endif /* SDL_THREAD_WINDOWS */
    147
    148/* vi: set ts=4 sw=4 expandtab: */