cscg22-gearboy

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

SDL_syscond.c (3746B)


      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#include <sys/time.h>
     24#include <unistd.h>
     25#include <errno.h>
     26#include <pthread.h>
     27
     28#include "SDL_thread.h"
     29#include "SDL_sysmutex_c.h"
     30
     31struct SDL_cond
     32{
     33    pthread_cond_t cond;
     34};
     35
     36/* Create a condition variable */
     37SDL_cond *
     38SDL_CreateCond(void)
     39{
     40    SDL_cond *cond;
     41
     42    cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
     43    if (cond) {
     44        if (pthread_cond_init(&cond->cond, NULL) < 0) {
     45            SDL_SetError("pthread_cond_init() failed");
     46            SDL_free(cond);
     47            cond = NULL;
     48        }
     49    }
     50    return (cond);
     51}
     52
     53/* Destroy a condition variable */
     54void
     55SDL_DestroyCond(SDL_cond * cond)
     56{
     57    if (cond) {
     58        pthread_cond_destroy(&cond->cond);
     59        SDL_free(cond);
     60    }
     61}
     62
     63/* Restart one of the threads that are waiting on the condition variable */
     64int
     65SDL_CondSignal(SDL_cond * cond)
     66{
     67    int retval;
     68
     69    if (!cond) {
     70        return SDL_SetError("Passed a NULL condition variable");
     71    }
     72
     73    retval = 0;
     74    if (pthread_cond_signal(&cond->cond) != 0) {
     75        return SDL_SetError("pthread_cond_signal() failed");
     76    }
     77    return retval;
     78}
     79
     80/* Restart all threads that are waiting on the condition variable */
     81int
     82SDL_CondBroadcast(SDL_cond * cond)
     83{
     84    int retval;
     85
     86    if (!cond) {
     87        return SDL_SetError("Passed a NULL condition variable");
     88    }
     89
     90    retval = 0;
     91    if (pthread_cond_broadcast(&cond->cond) != 0) {
     92        return SDL_SetError("pthread_cond_broadcast() failed");
     93    }
     94    return retval;
     95}
     96
     97int
     98SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
     99{
    100    int retval;
    101    struct timeval delta;
    102    struct timespec abstime;
    103
    104    if (!cond) {
    105        return SDL_SetError("Passed a NULL condition variable");
    106    }
    107
    108    gettimeofday(&delta, NULL);
    109
    110    abstime.tv_sec = delta.tv_sec + (ms / 1000);
    111    abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
    112    if (abstime.tv_nsec > 1000000000) {
    113        abstime.tv_sec += 1;
    114        abstime.tv_nsec -= 1000000000;
    115    }
    116
    117  tryagain:
    118    retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
    119    switch (retval) {
    120    case EINTR:
    121        goto tryagain;
    122        break;
    123    case ETIMEDOUT:
    124        retval = SDL_MUTEX_TIMEDOUT;
    125        break;
    126    case 0:
    127        break;
    128    default:
    129        retval = SDL_SetError("pthread_cond_timedwait() failed");
    130    }
    131    return retval;
    132}
    133
    134/* Wait on the condition variable, unlocking the provided mutex.
    135   The mutex must be locked before entering this function!
    136 */
    137int
    138SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
    139{
    140    if (!cond) {
    141        return SDL_SetError("Passed a NULL condition variable");
    142    } else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
    143        return SDL_SetError("pthread_cond_wait() failed");
    144    }
    145    return 0;
    146}
    147
    148/* vi: set ts=4 sw=4 expandtab: */