cscg22-gearboy

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

SDL_sysmutex.c (3345B)


      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 semaphore */
     72int
     73SDL_mutexP(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/* Unlock the mutex */
    102int
    103SDL_mutexV(SDL_mutex * mutex)
    104{
    105#if SDL_THREADS_DISABLED
    106    return 0;
    107#else
    108    if (mutex == NULL) {
    109        return SDL_SetError("Passed a NULL mutex");
    110    }
    111
    112    /* If we don't own the mutex, we can't unlock it */
    113    if (SDL_ThreadID() != mutex->owner) {
    114        return SDL_SetError("mutex not owned by this thread");
    115    }
    116
    117    if (mutex->recursive) {
    118        --mutex->recursive;
    119    } else {
    120        /* The order of operations is important.
    121           First reset the owner so another thread doesn't lock
    122           the mutex and set the ownership before we reset it,
    123           then release the lock semaphore.
    124         */
    125        mutex->owner = 0;
    126        SDL_SemPost(mutex->sem);
    127    }
    128    return 0;
    129#endif /* SDL_THREADS_DISABLED */
    130}
    131
    132/* vi: set ts=4 sw=4 expandtab: */