cscg22-gearboy

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

SDL_sysmutex.c (4095B)


      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/* An implementation of mutexes using semaphores */
     24
     25#include "SDL_thread.h"
     26#include "SDL_systhread_c.h"
     27
     28
     29struct SDL_mutex
     30{
     31    int recursive;
     32    SDL_threadID owner;
     33    SDL_sem *sem;
     34};
     35
     36/* Create a mutex */
     37SDL_mutex *
     38SDL_CreateMutex(void)
     39{
     40    SDL_mutex *mutex;
     41
     42    /* Allocate mutex memory */
     43    mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
     44    if (mutex) {
     45        /* Create the mutex semaphore, with initial value 1 */
     46        mutex->sem = SDL_CreateSemaphore(1);
     47        mutex->recursive = 0;
     48        mutex->owner = 0;
     49        if (!mutex->sem) {
     50            SDL_free(mutex);
     51            mutex = NULL;
     52        }
     53    } else {
     54        SDL_OutOfMemory();
     55    }
     56    return mutex;
     57}
     58
     59/* Free the mutex */
     60void
     61SDL_DestroyMutex(SDL_mutex * mutex)
     62{
     63    if (mutex) {
     64        if (mutex->sem) {
     65            SDL_DestroySemaphore(mutex->sem);
     66        }
     67        SDL_free(mutex);
     68    }
     69}
     70
     71/* Lock the mutex */
     72int
     73SDL_LockMutex(SDL_mutex * mutex)
     74{
     75#if SDL_THREADS_DISABLED
     76    return 0;
     77#else
     78    SDL_threadID this_thread;
     79
     80    if (mutex == NULL) {
     81        return SDL_SetError("Passed a NULL mutex");
     82    }
     83
     84    this_thread = SDL_ThreadID();
     85    if (mutex->owner == this_thread) {
     86        ++mutex->recursive;
     87    } else {
     88        /* The order of operations is important.
     89           We set the locking thread id after we obtain the lock
     90           so unlocks from other threads will fail.
     91         */
     92        SDL_SemWait(mutex->sem);
     93        mutex->owner = this_thread;
     94        mutex->recursive = 0;
     95    }
     96
     97    return 0;
     98#endif /* SDL_THREADS_DISABLED */
     99}
    100
    101/* try Lock the mutex */
    102int
    103SDL_TryLockMutex(SDL_mutex * mutex)
    104{
    105#if SDL_THREADS_DISABLED
    106    return 0;
    107#else
    108    int retval = 0;
    109    SDL_threadID this_thread;
    110
    111    if (mutex == NULL) {
    112        return SDL_SetError("Passed a NULL mutex");
    113    }
    114
    115    this_thread = SDL_ThreadID();
    116    if (mutex->owner == this_thread) {
    117        ++mutex->recursive;
    118    } else {
    119        /* The order of operations is important.
    120         We set the locking thread id after we obtain the lock
    121         so unlocks from other threads will fail.
    122         */
    123        retval = SDL_SemWait(mutex->sem);
    124        if (retval == 0) {
    125            mutex->owner = this_thread;
    126            mutex->recursive = 0;
    127        }
    128    }
    129
    130    return retval;
    131#endif /* SDL_THREADS_DISABLED */
    132}
    133
    134/* Unlock the mutex */
    135int
    136SDL_mutexV(SDL_mutex * mutex)
    137{
    138#if SDL_THREADS_DISABLED
    139    return 0;
    140#else
    141    if (mutex == NULL) {
    142        return SDL_SetError("Passed a NULL mutex");
    143    }
    144
    145    /* If we don't own the mutex, we can't unlock it */
    146    if (SDL_ThreadID() != mutex->owner) {
    147        return SDL_SetError("mutex not owned by this thread");
    148    }
    149
    150    if (mutex->recursive) {
    151        --mutex->recursive;
    152    } else {
    153        /* The order of operations is important.
    154           First reset the owner so another thread doesn't lock
    155           the mutex and set the ownership before we reset it,
    156           then release the lock semaphore.
    157         */
    158        mutex->owner = 0;
    159        SDL_SemPost(mutex->sem);
    160    }
    161    return 0;
    162#endif /* SDL_THREADS_DISABLED */
    163}
    164
    165/* vi: set ts=4 sw=4 expandtab: */