sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_syssem.c (4628B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 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_OS2
     24 
     25 /* An implementation of semaphores for OS/2 */
     26 
     27 #include "SDL_thread.h"
     28 #include "../../core/os2/SDL_os2.h"
     29 
     30 #define INCL_DOSSEMAPHORES
     31 #define INCL_DOSERRORS
     32 #define INCL_DOSMISC
     33 #include <os2.h>
     34 
     35 struct SDL_semaphore {
     36     HEV     hEv;
     37     HMTX    hMtx;
     38     ULONG   cPost;
     39 };
     40 
     41 
     42 SDL_sem *
     43 SDL_CreateSemaphore(Uint32 initial_value)
     44 {
     45     ULONG ulRC;
     46     SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem));
     47 
     48     if (pSDLSem == NULL) {
     49         SDL_OutOfMemory();
     50         return NULL;
     51     }
     52 
     53     ulRC = DosCreateEventSem(NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE);
     54     if (ulRC != NO_ERROR) {
     55         debug_os2("DosCreateEventSem(), rc = %u", ulRC);
     56         SDL_free(pSDLSem);
     57         return NULL;
     58     }
     59 
     60     ulRC = DosCreateMutexSem(NULL, &pSDLSem->hMtx, 0, FALSE);
     61     if (ulRC != NO_ERROR) {
     62         debug_os2("DosCreateMutexSem(), rc = %u", ulRC);
     63         DosCloseEventSem(pSDLSem->hEv);
     64         SDL_free(pSDLSem);
     65         return NULL;
     66     }
     67 
     68     pSDLSem->cPost = initial_value;
     69 
     70     return pSDLSem;
     71 }
     72 
     73 void
     74 SDL_DestroySemaphore(SDL_sem * sem)
     75 {
     76     if (!sem) return;
     77 
     78     DosCloseMutexSem(sem->hMtx);
     79     DosCloseEventSem(sem->hEv);
     80     SDL_free(sem);
     81 }
     82 
     83 int
     84 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
     85 {
     86     ULONG ulRC;
     87     ULONG ulStartTime, ulCurTime;
     88     ULONG ulTimeout;
     89     ULONG cPost;
     90 
     91     if (sem == NULL)
     92         return SDL_SetError("Passed a NULL sem");
     93 
     94     if (timeout != SEM_INDEFINITE_WAIT)
     95         DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG));
     96 
     97     while (TRUE) {
     98         ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
     99         if (ulRC != NO_ERROR)
    100             return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
    101 
    102         cPost = sem->cPost;
    103         if (sem->cPost != 0)
    104             sem->cPost--;
    105 
    106         DosReleaseMutexSem(sem->hMtx);
    107 
    108         if (cPost != 0)
    109             break;
    110 
    111         if (timeout == SEM_INDEFINITE_WAIT)
    112             ulTimeout = SEM_INDEFINITE_WAIT;
    113         else {
    114             DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG));
    115             ulTimeout = ulCurTime - ulStartTime;
    116             if (timeout < ulTimeout)
    117                 return SDL_MUTEX_TIMEDOUT;
    118             ulTimeout = timeout - ulTimeout;
    119         }
    120 
    121         ulRC = DosWaitEventSem(sem->hEv, ulTimeout);
    122         if (ulRC == ERROR_TIMEOUT)
    123             return SDL_MUTEX_TIMEDOUT;
    124 
    125         if (ulRC != NO_ERROR)
    126             return SDL_SetError("DosWaitEventSem() failed, rc = %u", ulRC);
    127     }
    128 
    129     return 0;
    130 }
    131 
    132 int
    133 SDL_SemTryWait(SDL_sem * sem)
    134 {
    135     return SDL_SemWaitTimeout(sem, 0);
    136 }
    137 
    138 int
    139 SDL_SemWait(SDL_sem * sem)
    140 {
    141     return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
    142 }
    143 
    144 Uint32
    145 SDL_SemValue(SDL_sem * sem)
    146 {
    147     ULONG ulRC;
    148 
    149     if (sem == NULL) {
    150         SDL_SetError("Passed a NULL sem");
    151         return 0;
    152     }
    153 
    154     ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
    155     if (ulRC != NO_ERROR)
    156         return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
    157 
    158     ulRC = sem->cPost;
    159     DosReleaseMutexSem(sem->hMtx);
    160 
    161     return ulRC;
    162 }
    163 
    164 int
    165 SDL_SemPost(SDL_sem * sem)
    166 {
    167     ULONG ulRC;
    168 
    169     if (sem == NULL)
    170         return SDL_SetError("Passed a NULL sem");
    171 
    172     ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
    173     if (ulRC != NO_ERROR)
    174         return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
    175 
    176     sem->cPost++;
    177 
    178     ulRC = DosPostEventSem(sem->hEv);
    179     if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
    180         debug_os2("DosPostEventSem() failed, rc = %u", ulRC);
    181     }
    182 
    183     DosReleaseMutexSem(sem->hMtx);
    184 
    185     return 0;
    186 }
    187 
    188 #endif /* SDL_THREAD_OS2 */
    189 
    190 /* vi: set ts=4 sw=4 expandtab: */