SDL_systimer.c (4490B)
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_TIMER_OS2 24 25 #include "SDL_timer.h" 26 #include "../../core/os2/SDL_os2.h" 27 28 #define INCL_DOSERRORS 29 #define INCL_DOSMISC 30 #define INCL_DOSPROFILE 31 #define INCL_DOSSEMAPHORES 32 #define INCL_DOSDATETIME 33 #define INCL_DOSPROCESS 34 #define INCL_DOSEXCEPTIONS 35 #include <os2.h> 36 37 /* No need to switch priorities in SDL_Delay() for OS/2 versions > Warp3 fp 42, */ 38 /*#define _SWITCH_PRIORITY*/ 39 40 typedef unsigned long long ULLONG; 41 42 static ULONG ulTmrFreq = 0; 43 static ULLONG ullTmrStart; 44 45 void 46 SDL_TicksInit(void) 47 { 48 ULONG ulRC; 49 50 ulRC = DosTmrQueryFreq(&ulTmrFreq); 51 if (ulRC != NO_ERROR) { 52 debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC); 53 } else { 54 ulRC = DosTmrQueryTime((PQWORD)&ullTmrStart); 55 if (ulRC == NO_ERROR) 56 return; 57 debug_os2("DosTmrQueryTime() failed, rc = %u", ulRC); 58 } 59 60 ulTmrFreq = 0; /* Error - use DosQuerySysInfo() for timer. */ 61 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrStart, sizeof(ULONG)); 62 } 63 64 void 65 SDL_TicksQuit(void) 66 { 67 } 68 69 Uint32 70 SDL_GetTicks(void) 71 { 72 ULONG ulResult; 73 ULLONG ullTmrNow; 74 75 if (ulTmrFreq == 0) /* Was not initialized. */ 76 SDL_TicksInit(); 77 78 if (ulTmrFreq != 0) { 79 DosTmrQueryTime((PQWORD)&ullTmrNow); 80 ulResult = (ullTmrNow - ullTmrStart) * 1000 / ulTmrFreq; 81 } else { 82 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrNow, sizeof(ULONG)); 83 ulResult = (ULONG)ullTmrNow - (ULONG)ullTmrStart; 84 } 85 86 return ulResult; 87 } 88 89 Uint64 90 SDL_GetPerformanceCounter(void) 91 { 92 QWORD qwTmrNow; 93 94 if (ulTmrFreq == 0 || (DosTmrQueryTime(&qwTmrNow) != NO_ERROR)) 95 return SDL_GetTicks(); 96 97 return *((Uint64 *)&qwTmrNow); 98 } 99 100 Uint64 101 SDL_GetPerformanceFrequency(void) 102 { 103 return (ulTmrFreq == 0)? 1000 : (Uint64)ulTmrFreq; 104 } 105 106 void 107 SDL_Delay(Uint32 ms) 108 { 109 HTIMER hTimer = NULLHANDLE; 110 ULONG ulRC; 111 #ifdef _SWITCH_PRIORITY 112 PPIB pib; 113 PTIB tib; 114 BOOL fSetPriority = ms < 50; 115 ULONG ulSavePriority; 116 ULONG ulNesting; 117 #endif 118 HEV hevTimer; 119 120 if (ms == 0) { 121 DosSleep(0); 122 return; 123 } 124 125 ulRC = DosCreateEventSem(NULL, &hevTimer, DC_SEM_SHARED, FALSE); 126 if (ulRC != NO_ERROR) { 127 debug_os2("DosAsyncTimer() failed, rc = %u", ulRC); 128 DosSleep(ms); 129 return; 130 } 131 132 #ifdef _SWITCH_PRIORITY 133 if (fSetPriority) { 134 if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR) 135 fSetPriority = FALSE; 136 else { 137 ulSavePriority = tib->tib_ptib2->tib2_ulpri; 138 if (((ulSavePriority & 0xFF00) == 0x0300) || /* already have high pr. */ 139 (DosEnterMustComplete( &ulNesting) != NO_ERROR)) 140 fSetPriority = FALSE; 141 else { 142 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); 143 } 144 } 145 } 146 #endif 147 148 DosResetEventSem(hevTimer, &ulRC); 149 ulRC = DosAsyncTimer(ms, (HSEM)hevTimer, &hTimer); 150 151 #ifdef _SWITCH_PRIORITY 152 if (fSetPriority) { 153 if (DosSetPriority(PRTYS_THREAD, (ulSavePriority >> 8) & 0xFF, 0, 0) == NO_ERROR) 154 DosSetPriority(PRTYS_THREAD, 0, ulSavePriority & 0xFF, 0); 155 DosExitMustComplete(&ulNesting); 156 } 157 #endif 158 159 if (ulRC != NO_ERROR) { 160 debug_os2("DosAsyncTimer() failed, rc = %u", ulRC); 161 } else { 162 DosWaitEventSem(hevTimer, SEM_INDEFINITE_WAIT); 163 } 164 165 if (ulRC != NO_ERROR) 166 DosSleep(ms); 167 168 DosCloseEventSem(hevTimer); 169 } 170 171 #endif /* SDL_TIMER_OS2 */ 172 173 /* vi: set ts=4 sw=4 expandtab: */