mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-28 15:52:39 +02:00
wait: Doxygen
This commit is contained in:
parent
6a6f654526
commit
eb01ccd097
@ -1,6 +1,5 @@
|
||||
// Copyright 2018 plutoo
|
||||
#pragma once
|
||||
#include "../kernel/mutex.h"
|
||||
#include "../kernel/wait.h"
|
||||
|
||||
typedef struct UsermodeEvent UsermodeEvent;
|
||||
@ -12,6 +11,21 @@ struct UsermodeEvent
|
||||
bool auto_clear;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a usermode event.
|
||||
* @param[out] e UsermodeEvent object.
|
||||
* @param[in] bool auto_clear Whether to automatically clear the event.
|
||||
* @note It is safe to wait on this event with several threads simultaneously.
|
||||
* @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees.
|
||||
*/
|
||||
void ueventCreate(UsermodeEvent* e, bool auto_clear);
|
||||
/**
|
||||
* @brief Clears the event signal.
|
||||
* @param[in] e UsermodeEvent object.
|
||||
*/
|
||||
void ueventClear(UsermodeEvent* e);
|
||||
/**
|
||||
* @brief Signals the event.
|
||||
* @param[in] e UsermodeEvent object.
|
||||
*/
|
||||
void ueventSignal(UsermodeEvent* e);
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Copyright 2018 plutoo
|
||||
#pragma once
|
||||
#include "../kernel/mutex.h"
|
||||
#include "../kernel/wait.h"
|
||||
|
||||
typedef struct UsermodeTimer UsermodeTimer;
|
||||
@ -12,6 +11,23 @@ struct UsermodeTimer
|
||||
u64 interval;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a usermode timer.
|
||||
* @param[out] t UsermodeTimer object.
|
||||
* @param[in] interval Interval (in nanoseconds).
|
||||
* @param[in] start Whether to start the timer right away.
|
||||
* @note It is safe to wait on this timer with several threads simultaneously.
|
||||
* @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees.
|
||||
* @note If the timer triggers twice before you wait on it, you will only get one signal.
|
||||
*/
|
||||
void utimerCreate(UsermodeTimer* t, u64 interval, bool start);
|
||||
/**
|
||||
* @brief Starts the timer.
|
||||
* @param[in] t UsermodeTimer object.
|
||||
*/
|
||||
void utimerStart(UsermodeTimer* t);
|
||||
/**
|
||||
* @brief Stops the timer.
|
||||
* @param[in] t UsermodeTimer object.
|
||||
*/
|
||||
void utimerStop(UsermodeTimer* t);
|
||||
|
@ -58,6 +58,7 @@ typedef struct {
|
||||
};
|
||||
} Waiter;
|
||||
|
||||
/// Creates a waiter for a kernelmode handle.
|
||||
static inline Waiter waiterForHandle(Handle h)
|
||||
{
|
||||
Waiter wait_obj;
|
||||
@ -66,6 +67,7 @@ static inline Waiter waiterForHandle(Handle h)
|
||||
return wait_obj;
|
||||
}
|
||||
|
||||
/// Creates a waiter for a usermode timer.
|
||||
static inline Waiter waiterForUtimer(UsermodeTimer* t)
|
||||
{
|
||||
Waiter wait_obj;
|
||||
@ -74,6 +76,7 @@ static inline Waiter waiterForUtimer(UsermodeTimer* t)
|
||||
return wait_obj;
|
||||
}
|
||||
|
||||
/// Creates a waiter for a usermode event.
|
||||
static inline Waiter waiterForUevent(UsermodeEvent* e)
|
||||
{
|
||||
Waiter wait_obj;
|
||||
@ -82,16 +85,23 @@ static inline Waiter waiterForUevent(UsermodeEvent* e)
|
||||
return wait_obj;
|
||||
}
|
||||
|
||||
/// Creates a waiter for a kernelmode event.
|
||||
static inline Waiter waiterForEvent(Event* e) {
|
||||
return waiterForHandle(e->revent);
|
||||
}
|
||||
|
||||
/// Creates a waiter for a thread exit.
|
||||
static inline Waiter waiterForThreadExit(Thread* t) {
|
||||
return waiterForHandle(t->handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits for an arbitrary number of waiters. This is a macro that uses var-args.
|
||||
* @param[out] idx_out The index of the signalled waiter.
|
||||
* @param[in] timeout Timeout (in nanoseconds).
|
||||
* @note The number of waiters must be less than 64. This is a Horizon kernel limitation.
|
||||
*/
|
||||
#define waitMulti(idx_out, timeout, ...) \
|
||||
waitN((idx_out), (timeout), (Waiter[]) { __VA_ARGS__ }, sizeof((Waiter[]) { __VA_ARGS__ }) / sizeof(Waiter))
|
||||
|
||||
|
||||
Result waitN(s32* idx_out, u64 timeout, Waiter* objects, size_t num_objects);
|
||||
|
@ -69,7 +69,7 @@ static Result waitImpl(s32* idx_out, u64 timeout, Waiter* objects, size_t num_ob
|
||||
}
|
||||
|
||||
// Always add a listener on the timer,
|
||||
// So that we can detect another thread were to stopping/starting it during our waiting.
|
||||
// If the timer is started/stopped we want to detect that.
|
||||
_utimerAddListener(
|
||||
obj->timer, &waiters[num_waiters], num_waiters, &triggered_idx,
|
||||
own_thread_handle);
|
||||
@ -111,8 +111,9 @@ static Result waitImpl(s32* idx_out, u64 timeout, Waiter* objects, size_t num_ob
|
||||
if (rc == KernelError_Timeout)
|
||||
{
|
||||
// If we hit the user-supplied timeout, we return the timeout error back to caller.
|
||||
if (end_tick_idx == -1)
|
||||
if (end_tick_idx == -1) {
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
// If not, it means a timer triggered the timeout.
|
||||
_utimerRecalculate(objects[end_tick_idx].timer, end_tick + cur_tick);
|
||||
@ -134,6 +135,7 @@ static Result waitImpl(s32* idx_out, u64 timeout, Waiter* objects, size_t num_ob
|
||||
{
|
||||
case WaiterNodeType_Event:
|
||||
_ueventTryAutoClear(waiters[triggered_idx].parent_event);
|
||||
|
||||
*idx_out = triggered_idx;
|
||||
rc = 0;
|
||||
break;
|
||||
@ -171,8 +173,9 @@ Result waitN(s32* idx_out, u64 timeout, Waiter* objects, size_t num_objects)
|
||||
{
|
||||
u64 time_spent = armTicksToNs(armGetSystemTick() - cur_tick);
|
||||
|
||||
if (time_spent >= timeout)
|
||||
if (time_spent >= timeout) {
|
||||
return KernelError_Timeout;
|
||||
}
|
||||
|
||||
timeout -= time_spent;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user