Convert ticks to 64-bit, added nanosecond precision to the API

Fixes https://github.com/libsdl-org/SDL/issues/5512
Fixes https://github.com/libsdl-org/SDL/issues/6731
This commit is contained in:
Sam Lantinga
2022-12-02 01:17:17 -08:00
parent 764b899a13
commit 8121bbd083
96 changed files with 938 additions and 1243 deletions

View File

@@ -182,7 +182,7 @@ typedef enum
typedef struct SDL_CommonEvent
{
Uint32 type;
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
} SDL_CommonEvent;
/**
@@ -191,7 +191,7 @@ typedef struct SDL_CommonEvent
typedef struct SDL_DisplayEvent
{
Uint32 type; /**< ::SDL_DISPLAYEVENT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 display; /**< The associated display index */
Uint8 event; /**< ::SDL_DisplayEventID */
Uint8 padding1;
@@ -206,7 +206,7 @@ typedef struct SDL_DisplayEvent
typedef struct SDL_WindowEvent
{
Uint32 type; /**< ::SDL_WINDOWEVENT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The associated window */
Uint8 event; /**< ::SDL_WindowEventID */
Uint8 padding1;
@@ -222,7 +222,7 @@ typedef struct SDL_WindowEvent
typedef struct SDL_KeyboardEvent
{
Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 repeat; /**< Non-zero if this is a key repeat */
@@ -238,7 +238,7 @@ typedef struct SDL_KeyboardEvent
typedef struct SDL_TextEditingEvent
{
Uint32 type; /**< ::SDL_TEXTEDITING */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */
char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */
Sint32 start; /**< The start cursor of selected editing text */
@@ -252,7 +252,7 @@ typedef struct SDL_TextEditingEvent
typedef struct SDL_TextEditingExtEvent
{
Uint32 type; /**< ::SDL_TEXTEDITING_EXT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */
char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */
Sint32 start; /**< The start cursor of selected editing text */
@@ -266,7 +266,7 @@ typedef struct SDL_TextEditingExtEvent
typedef struct SDL_TextInputEvent
{
Uint32 type; /**< ::SDL_TEXTINPUT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */
} SDL_TextInputEvent;
@@ -277,7 +277,7 @@ typedef struct SDL_TextInputEvent
typedef struct SDL_MouseMotionEvent
{
Uint32 type; /**< ::SDL_MOUSEMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */
Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint32 state; /**< The current button state */
@@ -293,7 +293,7 @@ typedef struct SDL_MouseMotionEvent
typedef struct SDL_MouseButtonEvent
{
Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint8 button; /**< The mouse button index */
@@ -310,7 +310,7 @@ typedef struct SDL_MouseButtonEvent
typedef struct SDL_MouseWheelEvent
{
Uint32 type; /**< ::SDL_MOUSEWHEEL */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
@@ -328,7 +328,7 @@ typedef struct SDL_MouseWheelEvent
typedef struct SDL_JoyAxisEvent
{
Uint32 type; /**< ::SDL_JOYAXISMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Uint8 axis; /**< The joystick axis index */
Uint8 padding1;
@@ -344,7 +344,7 @@ typedef struct SDL_JoyAxisEvent
typedef struct SDL_JoyBallEvent
{
Uint32 type; /**< ::SDL_JOYBALLMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Uint8 ball; /**< The joystick trackball index */
Uint8 padding1;
@@ -360,7 +360,7 @@ typedef struct SDL_JoyBallEvent
typedef struct SDL_JoyHatEvent
{
Uint32 type; /**< ::SDL_JOYHATMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Uint8 hat; /**< The joystick hat index */
Uint8 value; /**< The hat position value.
@@ -380,7 +380,7 @@ typedef struct SDL_JoyHatEvent
typedef struct SDL_JoyButtonEvent
{
Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Uint8 button; /**< The joystick button index */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
@@ -394,7 +394,7 @@ typedef struct SDL_JoyButtonEvent
typedef struct SDL_JoyDeviceEvent
{
Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */
} SDL_JoyDeviceEvent;
@@ -404,7 +404,7 @@ typedef struct SDL_JoyDeviceEvent
typedef struct SDL_JoyBatteryEvent
{
Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
SDL_JoystickPowerLevel level; /**< The joystick battery level */
} SDL_JoyBatteryEvent;
@@ -415,7 +415,7 @@ typedef struct SDL_JoyBatteryEvent
typedef struct SDL_ControllerAxisEvent
{
Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */
Uint8 padding1;
@@ -432,7 +432,7 @@ typedef struct SDL_ControllerAxisEvent
typedef struct SDL_ControllerButtonEvent
{
Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Uint8 button; /**< The controller button (SDL_GameControllerButton) */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
@@ -447,7 +447,7 @@ typedef struct SDL_ControllerButtonEvent
typedef struct SDL_ControllerDeviceEvent
{
Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
} SDL_ControllerDeviceEvent;
@@ -457,7 +457,7 @@ typedef struct SDL_ControllerDeviceEvent
typedef struct SDL_ControllerTouchpadEvent
{
Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Sint32 touchpad; /**< The index of the touchpad */
Sint32 finger; /**< The index of the finger on the touchpad */
@@ -472,7 +472,7 @@ typedef struct SDL_ControllerTouchpadEvent
typedef struct SDL_ControllerSensorEvent
{
Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */
float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */
@@ -485,7 +485,7 @@ typedef struct SDL_ControllerSensorEvent
typedef struct SDL_AudioDeviceEvent
{
Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */
Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */
Uint8 padding1;
@@ -500,7 +500,7 @@ typedef struct SDL_AudioDeviceEvent
typedef struct SDL_TouchFingerEvent
{
Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchId; /**< The touch device id */
SDL_FingerID fingerId;
float x; /**< Normalized in the range 0...1 */
@@ -518,7 +518,7 @@ typedef struct SDL_TouchFingerEvent
typedef struct SDL_MultiGestureEvent
{
Uint32 type; /**< ::SDL_MULTIGESTURE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchId; /**< The touch device id */
float dTheta;
float dDist;
@@ -535,7 +535,7 @@ typedef struct SDL_MultiGestureEvent
typedef struct SDL_DollarGestureEvent
{
Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchId; /**< The touch device id */
SDL_GestureID gestureId;
Uint32 numFingers;
@@ -553,7 +553,7 @@ typedef struct SDL_DollarGestureEvent
typedef struct SDL_DropEvent
{
Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */
Uint32 windowID; /**< The window that was dropped on, if any */
} SDL_DropEvent;
@@ -565,7 +565,7 @@ typedef struct SDL_DropEvent
typedef struct SDL_SensorEvent
{
Uint32 type; /**< ::SDL_SENSORUPDATE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_SensorID which; /**< The instance ID of the sensor */
float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */
Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */
@@ -577,7 +577,7 @@ typedef struct SDL_SensorEvent
typedef struct SDL_QuitEvent
{
Uint32 type; /**< ::SDL_QUIT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
} SDL_QuitEvent;
/**
@@ -586,7 +586,7 @@ typedef struct SDL_QuitEvent
typedef struct SDL_OSEvent
{
Uint32 type; /**< ::SDL_QUIT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
} SDL_OSEvent;
/**
@@ -595,7 +595,7 @@ typedef struct SDL_OSEvent
typedef struct SDL_UserEvent
{
Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The associated window if any */
Sint32 code; /**< User defined event code */
void *data1; /**< User defined data pointer */
@@ -615,7 +615,7 @@ typedef struct SDL_SysWMmsg SDL_SysWMmsg;
typedef struct SDL_SysWMEvent
{
Uint32 type; /**< ::SDL_SYSWMEVENT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */
} SDL_SysWMEvent;
@@ -669,7 +669,7 @@ typedef union SDL_Event
the next multiple of 16, 64, and on architectures where pointers are
even larger the size of SDL_UserEvent will dominate as being 3 pointers.
*/
Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)];
Uint8 padding[128];
} SDL_Event;
/* Make sure we haven't broken binary compatibility */
@@ -879,6 +879,7 @@ extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
* \sa SDL_SetEventFilter
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout
* \sa SDL_WaitEventTimeoutNS
*/
extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event);
@@ -901,8 +902,9 @@ extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event);
* \sa SDL_PollEvent
* \sa SDL_PumpEvents
* \sa SDL_WaitEventTimeout
* \sa SDL_WaitEventTimeoutNS
*/
extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event);
extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event *event);
/**
* Wait until the specified timeout (in milliseconds) for the next available
@@ -914,10 +916,13 @@ extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event);
* As this function may implicitly call SDL_PumpEvents(), you can only call
* this function in the thread that initialized the video subsystem.
*
* The timeout is not guaranteed, the actual wait time could be longer
* due to system scheduling.
*
* \param event the SDL_Event structure to be filled in with the next event
* from the queue, or NULL
* \param timeout the maximum number of milliseconds to wait for the next
* available event
* \param timeoutMS the maximum number of milliseconds to wait for the next
* available event
* \returns 1 on success or 0 if there was an error while waiting for events;
* call SDL_GetError() for more information. This also returns 0 if
* the timeout elapsed without an event arriving.
@@ -927,9 +932,39 @@ extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event);
* \sa SDL_PollEvent
* \sa SDL_PumpEvents
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeoutNS
*/
extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event,
int timeout);
extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS);
/**
* Wait until the specified timeout (in nanoseconds) for the next available
* event.
*
* If `event` is not NULL, the next event is removed from the queue and stored
* in the SDL_Event structure pointed to by `event`.
*
* As this function may implicitly call SDL_PumpEvents(), you can only call
* this function in the thread that initialized the video subsystem.
*
* The timeout is not guaranteed, the actual wait time could be longer
* due to system scheduling.
*
* \param event the SDL_Event structure to be filled in with the next event
* from the queue, or NULL
* \param timeoutNS the maximum number of nanoseconds to wait for the next
* available event
* \returns 1 on success or 0 if there was an error while waiting for events;
* call SDL_GetError() for more information. This also returns 0 if
* the timeout elapsed without an event arriving.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_PollEvent
* \sa SDL_PumpEvents
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout
*/
extern DECLSPEC int SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);
/**
* Add an event to the event queue.

View File

@@ -46,7 +46,7 @@ extern "C" {
/**
* This is the timeout value which corresponds to never time out.
*/
#define SDL_MUTEX_MAXWAIT (~(Uint32)0)
#define SDL_MUTEX_MAXWAIT -1
/**
@@ -194,6 +194,7 @@ typedef struct SDL_semaphore SDL_sem;
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/
extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value);
@@ -213,8 +214,9 @@ extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value);
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/
extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem);
extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem);
/**
* Wait until a semaphore has a positive value and then decrements it.
@@ -240,8 +242,9 @@ extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem);
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/
extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem);
extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem *sem);
/**
* See if a semaphore has a positive value and decrement it if it does.
@@ -264,8 +267,9 @@ extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem);
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/
extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem);
extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem *sem);
/**
* Wait until a semaphore has a positive value and then decrements it.
@@ -276,7 +280,7 @@ extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem);
* successful it will atomically decrement the semaphore value.
*
* \param sem the semaphore to wait on
* \param timeout the length of the timeout, in milliseconds
* \param timeoutMS the length of the timeout, in milliseconds
* \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
* succeed in the allotted time, or a negative error code on failure;
* call SDL_GetError() for more information.
@@ -289,8 +293,35 @@ extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem);
* \sa SDL_SemTryWait
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeoutNS
*/
extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);
extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Sint32 timeoutMS);
/**
* Wait until a semaphore has a positive value and then decrements it.
*
* This function suspends the calling thread until either the semaphore
* pointed to by `sem` has a positive value, the call is interrupted by a
* signal or error, or the specified time has elapsed. If the call is
* successful it will atomically decrement the semaphore value.
*
* \param sem the semaphore to wait on
* \param timeoutNS the length of the timeout, in nanoseconds
* \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
* succeed in the allotted time, or a negative error code on failure;
* call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CreateSemaphore
* \sa SDL_DestroySemaphore
* \sa SDL_SemPost
* \sa SDL_SemTryWait
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
*/
extern DECLSPEC int SDLCALL SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS);
/**
* Atomically increment a semaphore's value and wake waiting threads.
@@ -308,7 +339,7 @@ extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
*/
extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem);
extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem *sem);
/**
* Get the current value of a semaphore.
@@ -320,7 +351,7 @@ extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem);
*
* \sa SDL_CreateSemaphore
*/
extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem);
extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem *sem);
/* @} *//* Semaphore functions */
@@ -346,6 +377,7 @@ typedef struct SDL_cond SDL_cond;
* \sa SDL_CondSignal
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_DestroyCond
*/
extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void);
@@ -361,9 +393,10 @@ extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void);
* \sa SDL_CondSignal
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond
*/
extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond);
extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond *cond);
/**
* Restart one of the threads that are waiting on the condition variable.
@@ -377,10 +410,11 @@ extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond);
* \sa SDL_CondBroadcast
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond
* \sa SDL_DestroyCond
*/
extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond);
extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond *cond);
/**
* Restart all threads that are waiting on the condition variable.
@@ -394,10 +428,11 @@ extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond);
* \sa SDL_CondSignal
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond
* \sa SDL_DestroyCond
*/
extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond);
extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond *cond);
/**
* Wait until a condition variable is signaled.
@@ -422,10 +457,11 @@ extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond);
* \sa SDL_CondBroadcast
* \sa SDL_CondSignal
* \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond
* \sa SDL_DestroyCond
*/
extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex);
/**
* Wait until a condition variable is signaled or a certain time has passed.
@@ -440,7 +476,7 @@ extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
*
* \param cond the condition variable to wait on
* \param mutex the mutex used to coordinate thread access
* \param ms the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT`
* \param timeoutMS the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT`
* to wait indefinitely
* \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if
* the condition is not signaled in the allotted time, or a negative
@@ -451,11 +487,42 @@ extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
* \sa SDL_CondBroadcast
* \sa SDL_CondSignal
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond
* \sa SDL_DestroyCond
*/
extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond,
SDL_mutex * mutex, Uint32 ms);
extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond *cond,
SDL_mutex *mutex, Sint32 timeoutMS);
/**
* Wait until a condition variable is signaled or a certain time has passed.
*
* This function unlocks the specified `mutex` and waits for another thread to
* call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable
* `cond`, or for the specified time to elapse. Once the condition variable is
* signaled or the time elapsed, the mutex is re-locked and the function
* returns.
*
* The mutex must be locked before calling this function.
*
* \param cond the condition variable to wait on
* \param mutex the mutex used to coordinate thread access
* \param timeoutNS the maximum time to wait, in nanoseconds, or `SDL_MUTEX_MAXWAIT` to wait indefinitely
* \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if
* the condition is not signaled in the allotted time, or a negative
* error code on failure; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CondBroadcast
* \sa SDL_CondSignal
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeout
* \sa SDL_CreateCond
* \sa SDL_DestroyCond
*/
extern DECLSPEC int SDLCALL SDL_CondWaitTimeoutNS(SDL_cond *cond,
SDL_mutex *mutex, Sint64 timeoutNS);
/* @} *//* Condition variable functions */

View File

@@ -38,72 +38,37 @@ extern "C" {
#endif
/**
* Get the number of milliseconds since SDL library initialization.
*
* This value wraps if the program runs for more than ~49 days.
*
* This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64()
* instead, where the value doesn't wrap every ~49 days. There are places in
* SDL where we provide a 32-bit timestamp that can not change without
* breaking binary compatibility, though, so this function isn't officially
* deprecated.
*
* \returns an unsigned 32-bit value representing the number of milliseconds
* since the SDL library initialized.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_TICKS_PASSED
* SDL time constants
*/
extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void);
#define SDL_MS_PER_SECOND 1000
#define SDL_US_PER_SECOND 1000000
#define SDL_NS_PER_SECOND 1000000000LLU
#define SDL_NS_PER_MS 1000000
#define SDL_NS_PER_US 1000
#define SDL_MS_TO_NS(MS) (((Uint64)(MS)) * SDL_NS_PER_MS)
#define SDL_NS_TO_MS(NS) ((NS) / SDL_NS_PER_MS)
#define SDL_US_TO_NS(US) (((Uint64)(US)) * SDL_NS_PER_US)
#define SDL_NS_TO_US(NS) ((NS) / SDL_NS_PER_US)
/**
* Get the number of milliseconds since SDL library initialization.
*
* Note that you should not use the SDL_TICKS_PASSED macro with values
* returned by this function, as that macro does clever math to compensate for
* the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit
* values from this function can be safely compared directly.
*
* For example, if you want to wait 100 ms, you could do this:
*
* ```c
* const Uint64 timeout = SDL_GetTicks64() + 100;
* while (SDL_GetTicks64() < timeout) {
* // ... do work until timeout has elapsed
* }
* ```
*
* \returns an unsigned 64-bit value representing the number of milliseconds
* since the SDL library initialized.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC Uint64 SDLCALL SDL_GetTicks64(void);
extern DECLSPEC Uint64 SDLCALL SDL_GetTicks(void);
/**
* Compare 32-bit SDL ticks values, and return true if `A` has passed `B`.
* Get the number of nanoseconds since SDL library initialization.
*
* This should be used with results from SDL_GetTicks(), as this macro
* attempts to deal with the 32-bit counter wrapping back to zero every ~49
* days, but should _not_ be used with SDL_GetTicks64(), which does not have
* that problem.
* \returns an unsigned 64-bit value representing the number of nanoseconds
* since the SDL library initialized.
*
* For example, with SDL_GetTicks(), if you want to wait 100 ms, you could
* do this:
*
* ```c
* const Uint32 timeout = SDL_GetTicks() + 100;
* while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
* // ... do work until timeout has elapsed
* }
* ```
*
* Note that this does not handle tick differences greater
* than 2^31 so take care when using the above kind of code
* with large timeout delays (tens of days).
* \since This function is available since SDL 3.0.0.
*/
#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
extern DECLSPEC Uint64 SDLCALL SDL_GetTicksNS(void);
/**
* Get the current value of the high resolution counter.
@@ -146,15 +111,28 @@ extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void);
*/
extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
/**
* Wait a specified number of nanoseconds before returning.
*
* This function waits a specified number of nanoseconds before returning. It
* waits at least the specified time, but possibly longer due to OS
* scheduling.
*
* \param ns the number of nanoseconds to delay
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC void SDLCALL SDL_DelayNS(Uint64 ns);
/**
* Function prototype for the timer callback function.
*
* The callback function is passed the current timer interval and returns
* the next timer interval. If the returned value is the same as the one
* the next timer interval, in milliseconds. If the returned value is the same as the one
* passed in, the periodic alarm continues, otherwise a new alarm is
* scheduled. If the callback returns 0, the periodic alarm is cancelled.
*/
typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param);
typedef Uint32 (SDLCALL *SDL_TimerCallback)(Uint32 interval, void *param);
/**
* Definition of the timer ID type.
@@ -179,7 +157,7 @@ typedef int SDL_TimerID;
* iteration.
*
* Timing may be inexact due to OS scheduling. Be sure to note the current
* time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your
* time with SDL_GetTicksNS() or SDL_GetPerformanceCounter() in case your
* callback needs to adjust for variances.
*
* \param interval the timer delay, in milliseconds, passed to `callback`