mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 13:02:38 +02:00
Stylefixes, part 1
This commit is contained in:
parent
eb7d835a79
commit
9144d78031
@ -1,29 +1,35 @@
|
|||||||
// Copyright 2018 plutoo
|
/**
|
||||||
|
* @file uevent.h
|
||||||
|
* @brief User-mode event synchronization primitive.
|
||||||
|
* @author plutoo
|
||||||
|
* @copyright libnx Authors
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../kernel/wait.h"
|
#include "wait.h"
|
||||||
|
|
||||||
typedef struct UEvent UEvent;
|
typedef struct UEvent UEvent;
|
||||||
|
|
||||||
struct UEvent
|
struct UEvent {
|
||||||
{
|
|
||||||
Waitable waitable;
|
Waitable waitable;
|
||||||
bool signal;
|
bool signal;
|
||||||
bool auto_clear;
|
bool auto_clear;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a usermode event.
|
* @brief Creates a user-mode event.
|
||||||
* @param[out] e UEvent object.
|
* @param[out] e UEvent object.
|
||||||
* @param[in] bool auto_clear Whether to automatically clear the event.
|
* @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 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.
|
* @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees.
|
||||||
*/
|
*/
|
||||||
void ueventCreate(UEvent* e, bool auto_clear);
|
void ueventCreate(UEvent* e, bool auto_clear);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears the event signal.
|
* @brief Clears the event signal.
|
||||||
* @param[in] e UEvent object.
|
* @param[in] e UEvent object.
|
||||||
*/
|
*/
|
||||||
void ueventClear(UEvent* e);
|
void ueventClear(UEvent* e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Signals the event.
|
* @brief Signals the event.
|
||||||
* @param[in] e UEvent object.
|
* @param[in] e UEvent object.
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
// Copyright 2018 plutoo
|
/**
|
||||||
|
* @file uevent.h
|
||||||
|
* @brief User-mode timer synchronization primitive.
|
||||||
|
* @author plutoo
|
||||||
|
* @copyright libnx Authors
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../kernel/wait.h"
|
#include "wait.h"
|
||||||
|
|
||||||
typedef struct UTimer UTimer;
|
typedef struct UTimer UTimer;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TimerType_OneShot,
|
TimerType_OneShot,
|
||||||
TimerType_Repeating
|
TimerType_Repeating,
|
||||||
} TimerType;
|
} TimerType;
|
||||||
|
|
||||||
struct UTimer
|
struct UTimer {
|
||||||
{
|
|
||||||
Waitable waitable;
|
Waitable waitable;
|
||||||
TimerType type;
|
TimerType type;
|
||||||
u64 next_tick;
|
u64 next_tick;
|
||||||
@ -18,7 +22,7 @@ struct UTimer
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a usermode timer.
|
* @brief Creates a user-mode timer.
|
||||||
* @param[out] t UTimer object.
|
* @param[out] t UTimer object.
|
||||||
* @param[in] interval Interval (in nanoseconds).
|
* @param[in] interval Interval (in nanoseconds).
|
||||||
* @param[in] type Timer type (repeating or one-shot)
|
* @param[in] type Timer type (repeating or one-shot)
|
||||||
@ -27,11 +31,13 @@ struct UTimer
|
|||||||
* @note For a repeating timer: If the timer triggers twice before you wait on it, you will only get one signal.
|
* @note For a repeating timer: If the timer triggers twice before you wait on it, you will only get one signal.
|
||||||
*/
|
*/
|
||||||
void utimerCreate(UTimer* t, u64 interval, TimerType type);
|
void utimerCreate(UTimer* t, u64 interval, TimerType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the timer.
|
* @brief Starts the timer.
|
||||||
* @param[in] t UTimer object.
|
* @param[in] t UTimer object.
|
||||||
*/
|
*/
|
||||||
void utimerStart(UTimer* t);
|
void utimerStart(UTimer* t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stops the timer.
|
* @brief Stops the timer.
|
||||||
* @param[in] t UTimer object.
|
* @param[in] t UTimer object.
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
// Copyright 2018 plutoo
|
/**
|
||||||
|
* @file wait.h
|
||||||
|
* @brief User mode synchronization primitive waiting operations.
|
||||||
|
* @author plutoo
|
||||||
|
* @copyright libnx Authors
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../kernel/mutex.h"
|
#include "mutex.h"
|
||||||
#include "../kernel/event.h"
|
#include "event.h"
|
||||||
#include "../kernel/thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
// Implementation details.
|
// Implementation details.
|
||||||
typedef struct UEvent UEvent;
|
typedef struct UEvent UEvent;
|
||||||
@ -10,14 +15,13 @@ typedef struct UTimer UTimer;
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WaiterNodeType_Event,
|
WaiterNodeType_Event,
|
||||||
WaiterNodeType_Timer
|
WaiterNodeType_Timer,
|
||||||
} WaiterNodeType;
|
} WaiterNodeType;
|
||||||
|
|
||||||
typedef struct Waitable Waitable;
|
typedef struct Waitable Waitable;
|
||||||
typedef struct WaitableNode WaitableNode;
|
typedef struct WaitableNode WaitableNode;
|
||||||
|
|
||||||
struct WaitableNode
|
struct WaitableNode {
|
||||||
{
|
|
||||||
WaitableNode* prev;
|
WaitableNode* prev;
|
||||||
WaitableNode* next;
|
WaitableNode* next;
|
||||||
};
|
};
|
||||||
@ -35,8 +39,7 @@ typedef struct {
|
|||||||
size_t* idx_out;
|
size_t* idx_out;
|
||||||
} WaiterNode;
|
} WaiterNode;
|
||||||
|
|
||||||
struct Waitable
|
struct Waitable {
|
||||||
{
|
|
||||||
WaitableNode list;
|
WaitableNode list;
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
};
|
};
|
||||||
@ -58,7 +61,7 @@ typedef struct {
|
|||||||
};
|
};
|
||||||
} Waiter;
|
} Waiter;
|
||||||
|
|
||||||
/// Creates a waiter for a kernelmode handle.
|
/// Creates a waiter for a kernel-mode handle.
|
||||||
static inline Waiter waiterForHandle(Handle h)
|
static inline Waiter waiterForHandle(Handle h)
|
||||||
{
|
{
|
||||||
Waiter wait_obj;
|
Waiter wait_obj;
|
||||||
@ -67,7 +70,7 @@ static inline Waiter waiterForHandle(Handle h)
|
|||||||
return wait_obj;
|
return wait_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a waiter for a usermode timer.
|
/// Creates a waiter for a user-mode timer.
|
||||||
static inline Waiter waiterForUTimer(UTimer* t)
|
static inline Waiter waiterForUTimer(UTimer* t)
|
||||||
{
|
{
|
||||||
Waiter wait_obj;
|
Waiter wait_obj;
|
||||||
@ -76,7 +79,7 @@ static inline Waiter waiterForUTimer(UTimer* t)
|
|||||||
return wait_obj;
|
return wait_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a waiter for a usermode event.
|
/// Creates a waiter for a user-mode event.
|
||||||
static inline Waiter waiterForUEvent(UEvent* e)
|
static inline Waiter waiterForUEvent(UEvent* e)
|
||||||
{
|
{
|
||||||
Waiter wait_obj;
|
Waiter wait_obj;
|
||||||
@ -85,13 +88,15 @@ static inline Waiter waiterForUEvent(UEvent* e)
|
|||||||
return wait_obj;
|
return wait_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a waiter for a kernelmode event.
|
/// Creates a waiter for a kernel-mode event.
|
||||||
static inline Waiter waiterForEvent(Event* e) {
|
static inline Waiter waiterForEvent(Event* e)
|
||||||
|
{
|
||||||
return waiterForHandle(e->revent);
|
return waiterForHandle(e->revent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a waiter for a thread exit.
|
/// Creates a waiter for a thread exit.
|
||||||
static inline Waiter waiterForThreadExit(Thread* t) {
|
static inline Waiter waiterForThreadExit(Thread* t)
|
||||||
|
{
|
||||||
return waiterForHandle(t->handle);
|
return waiterForHandle(t->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +126,8 @@ Result waitNHandle(s32* idx_out, Handle* handles, size_t num_handles, u64 timeou
|
|||||||
* @param[in] w The waiter to wait for.
|
* @param[in] w The waiter to wait for.
|
||||||
* @param[in] timeout Timeout (in nanoseconds).
|
* @param[in] timeout Timeout (in nanoseconds).
|
||||||
*/
|
*/
|
||||||
static inline Result waitSingle(Waiter w, u64 timeout) {
|
static inline Result waitSingle(Waiter w, u64 timeout)
|
||||||
|
{
|
||||||
s32 idx;
|
s32 idx;
|
||||||
return waitMulti(&idx, timeout, w);
|
return waitMulti(&idx, timeout, w);
|
||||||
}
|
}
|
||||||
@ -131,7 +137,8 @@ static inline Result waitSingle(Waiter w, u64 timeout) {
|
|||||||
* @param[in] h The handle to wait for.
|
* @param[in] h The handle to wait for.
|
||||||
* @param[in] timeout Timeout (in nanoseconds).
|
* @param[in] timeout Timeout (in nanoseconds).
|
||||||
*/
|
*/
|
||||||
static inline Result waitSingleHandle(Handle h, u64 timeout) {
|
static inline Result waitSingleHandle(Handle h, u64 timeout)
|
||||||
|
{
|
||||||
s32 idx;
|
s32 idx;
|
||||||
return waitMultiHandle(&idx, timeout, h);
|
return waitMultiHandle(&idx, timeout, h);
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,8 @@ void ueventSignal(UEvent* e)
|
|||||||
void _ueventTryAutoClear(UEvent* e)
|
void _ueventTryAutoClear(UEvent* e)
|
||||||
{
|
{
|
||||||
mutexLock(&e->waitable.mutex);
|
mutexLock(&e->waitable.mutex);
|
||||||
if (e->auto_clear) {
|
if (e->auto_clear)
|
||||||
e->signal = false;
|
e->signal = false;
|
||||||
}
|
|
||||||
mutexUnlock(&e->waitable.mutex);
|
mutexUnlock(&e->waitable.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,21 +43,13 @@ bool _ueventAddListener(UEvent* e, WaiterNode* w, size_t idx, size_t* idx_out, H
|
|||||||
mutexLock(&e->waitable.mutex);
|
mutexLock(&e->waitable.mutex);
|
||||||
|
|
||||||
bool signalled = e->signal;
|
bool signalled = e->signal;
|
||||||
bool ret;
|
|
||||||
|
|
||||||
if (signalled)
|
if (signalled) {
|
||||||
{
|
if (e->auto_clear)
|
||||||
if (e->auto_clear) {
|
|
||||||
e->signal = false;
|
e->signal = false;
|
||||||
}
|
} else
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_waiterNodeAddToWaitable(w, &e->waitable);
|
_waiterNodeAddToWaitable(w, &e->waitable);
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutexUnlock(&e->waitable.mutex);
|
mutexUnlock(&e->waitable.mutex);
|
||||||
return ret;
|
return !signalled;
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@ void utimerStart(UTimer* t)
|
|||||||
{
|
{
|
||||||
mutexLock(&t->waitable.mutex);
|
mutexLock(&t->waitable.mutex);
|
||||||
|
|
||||||
if (t->next_tick == STOPPED)
|
if (t->next_tick == STOPPED) {
|
||||||
{
|
|
||||||
u64 new_tick = armGetSystemTick() + t->interval;
|
u64 new_tick = armGetSystemTick() + t->interval;
|
||||||
t->next_tick = new_tick;
|
t->next_tick = new_tick;
|
||||||
_waitableSignalAllListeners(&t->waitable);
|
_waitableSignalAllListeners(&t->waitable);
|
||||||
@ -34,8 +33,7 @@ void utimerStop(UTimer* t)
|
|||||||
{
|
{
|
||||||
mutexLock(&t->waitable.mutex);
|
mutexLock(&t->waitable.mutex);
|
||||||
|
|
||||||
if (t->next_tick != STOPPED)
|
if (t->next_tick != STOPPED) {
|
||||||
{
|
|
||||||
t->next_tick = STOPPED;
|
t->next_tick = STOPPED;
|
||||||
_waitableSignalAllListeners(&t->waitable);
|
_waitableSignalAllListeners(&t->waitable);
|
||||||
}
|
}
|
||||||
@ -47,13 +45,11 @@ void _utimerRecalculate(UTimer* t, u64 old_tick)
|
|||||||
{
|
{
|
||||||
mutexLock(&t->waitable.mutex);
|
mutexLock(&t->waitable.mutex);
|
||||||
|
|
||||||
if (t->next_tick == old_tick)
|
if (t->next_tick == old_tick) {
|
||||||
{
|
|
||||||
u64 interval = t->interval;
|
u64 interval = t->interval;
|
||||||
u64 new_tick = 0;
|
u64 new_tick = 0;
|
||||||
|
|
||||||
switch (t->type)
|
switch (t->type) {
|
||||||
{
|
|
||||||
case TimerType_OneShot:
|
case TimerType_OneShot:
|
||||||
new_tick = STOPPED;
|
new_tick = STOPPED;
|
||||||
break;
|
break;
|
||||||
|
@ -37,24 +37,19 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti
|
|||||||
s32 end_tick_idx = -1;
|
s32 end_tick_idx = -1;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i=0; i<num_objects; i++)
|
for (i = 0; i < num_objects; i ++) {
|
||||||
{
|
|
||||||
Waiter* obj = &objects[i];
|
Waiter* obj = &objects[i];
|
||||||
u64 timer_tick;
|
u64 timer_tick;
|
||||||
bool added;
|
bool added;
|
||||||
|
|
||||||
switch (obj->type)
|
switch (obj->type) {
|
||||||
{
|
|
||||||
case WaiterType_UTimer:
|
case WaiterType_UTimer:
|
||||||
|
|
||||||
timer_tick = _utimerGetNextTick(obj->timer);
|
timer_tick = _utimerGetNextTick(obj->timer);
|
||||||
|
|
||||||
// Skip timer if stopped.
|
// Skip timer if stopped.
|
||||||
if (timer_tick != 0)
|
if (timer_tick != 0) {
|
||||||
{
|
|
||||||
// If the timer already signalled, we're done.
|
// If the timer already signalled, we're done.
|
||||||
if (timer_tick < cur_tick)
|
if (timer_tick < cur_tick) {
|
||||||
{
|
|
||||||
_utimerRecalculate(obj->timer, timer_tick);
|
_utimerRecalculate(obj->timer, timer_tick);
|
||||||
|
|
||||||
*idx_out = i;
|
*idx_out = i;
|
||||||
@ -63,8 +58,7 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override the user-supplied timeout if timer would fire before that.
|
// Override the user-supplied timeout if timer would fire before that.
|
||||||
if ((timer_tick - cur_tick) < end_tick)
|
if ((timer_tick - cur_tick) < end_tick) {
|
||||||
{
|
|
||||||
end_tick = timer_tick - cur_tick;
|
end_tick = timer_tick - cur_tick;
|
||||||
end_tick_idx = i;
|
end_tick_idx = i;
|
||||||
}
|
}
|
||||||
@ -80,15 +74,13 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WaiterType_UEvent:
|
case WaiterType_UEvent:
|
||||||
|
|
||||||
// Try to add a listener to the event, if it hasn't already signalled.
|
// Try to add a listener to the event, if it hasn't already signalled.
|
||||||
added = _ueventAddListener(
|
added = _ueventAddListener(
|
||||||
obj->event, &waiters[num_waiters], num_waiters, &triggered_idx,
|
obj->event, &waiters[num_waiters], num_waiters, &triggered_idx,
|
||||||
own_thread_handle);
|
own_thread_handle);
|
||||||
|
|
||||||
// If the event already happened, we're done.
|
// If the event already happened, we're done.
|
||||||
if (!added)
|
if (!added) {
|
||||||
{
|
|
||||||
*idx_out = i;
|
*idx_out = i;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
goto clean_up;
|
goto clean_up;
|
||||||
@ -110,21 +102,17 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti
|
|||||||
// Do the actual syscall.
|
// Do the actual syscall.
|
||||||
rc = svcWaitSynchronization(idx_out, handles, num_objects, armTicksToNs(end_tick));
|
rc = svcWaitSynchronization(idx_out, handles, num_objects, armTicksToNs(end_tick));
|
||||||
|
|
||||||
if (rc == KernelError_Timeout)
|
if (rc == KernelError_Timeout) {
|
||||||
{
|
|
||||||
// If we hit the user-supplied timeout, we return the timeout error back to caller.
|
// 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;
|
goto clean_up;
|
||||||
}
|
|
||||||
|
|
||||||
// If not, it means a timer triggered the timeout.
|
// If not, it means a timer triggered the timeout.
|
||||||
_utimerRecalculate(objects[end_tick_idx].timer, end_tick + cur_tick);
|
_utimerRecalculate(objects[end_tick_idx].timer, end_tick + cur_tick);
|
||||||
|
|
||||||
*idx_out = end_tick_idx;
|
*idx_out = end_tick_idx;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
} else if (rc == KernelError_Canceled) {
|
||||||
else if (rc == KernelError_Canceled)
|
|
||||||
{
|
|
||||||
// If no listener filled in its own index, we return the interrupt error back to caller.
|
// If no listener filled in its own index, we return the interrupt error back to caller.
|
||||||
// This only happens if user for some reason manually does a svcCancelSynchronization.
|
// This only happens if user for some reason manually does a svcCancelSynchronization.
|
||||||
// Check just in case.
|
// Check just in case.
|
||||||
@ -133,8 +121,7 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti
|
|||||||
|
|
||||||
// An event was signalled, or a timer was updated.
|
// An event was signalled, or a timer was updated.
|
||||||
// So.. which is it?
|
// So.. which is it?
|
||||||
switch (waiters[triggered_idx].type)
|
switch (waiters[triggered_idx].type) {
|
||||||
{
|
|
||||||
case WaiterNodeType_Event:
|
case WaiterNodeType_Event:
|
||||||
_ueventTryAutoClear(waiters[triggered_idx].parent_event);
|
_ueventTryAutoClear(waiters[triggered_idx].parent_event);
|
||||||
|
|
||||||
@ -149,49 +136,45 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
clean_up:
|
clean_up:
|
||||||
|
|
||||||
// Remove listeners.
|
// Remove listeners.
|
||||||
for (i=0; i<num_waiters; i++) {
|
for (i = 0; i < num_waiters; i ++)
|
||||||
_waiterNodeFree(&waiters[i]);
|
_waiterNodeFree(&waiters[i]);
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result _waitLoop(WaitImplFunc wait, s32* idx_out, void* objects, size_t num_objects, u64 timeout)
|
static Result _waitLoop(WaitImplFunc wait, s32* idx_out, void* objects, size_t num_objects, u64 timeout)
|
||||||
{
|
{
|
||||||
while (1)
|
Result rc;
|
||||||
{
|
do {
|
||||||
u64 cur_tick = armGetSystemTick();
|
u64 cur_tick = armGetSystemTick();
|
||||||
Result rc = wait(idx_out, objects, num_objects, timeout);
|
rc = wait(idx_out, objects, num_objects, timeout);
|
||||||
|
|
||||||
if (rc == KernelError_Canceled)
|
if (rc == KernelError_Canceled) {
|
||||||
{
|
|
||||||
// On timer stop/start an interrupt is sent to listeners.
|
// On timer stop/start an interrupt is sent to listeners.
|
||||||
// It means the timer state has changed, and we should restart the wait.
|
// It means the timer state has changed, and we should restart the wait.
|
||||||
|
|
||||||
// Adjust timeout..
|
// Adjust timeout..
|
||||||
if (timeout != -1)
|
if (timeout != -1) {
|
||||||
{
|
|
||||||
u64 time_spent = armTicksToNs(armGetSystemTick() - cur_tick);
|
u64 time_spent = armTicksToNs(armGetSystemTick() - cur_tick);
|
||||||
|
|
||||||
if (time_spent >= timeout) {
|
if (time_spent < timeout)
|
||||||
return KernelError_Timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout -= time_spent;
|
timeout -= time_spent;
|
||||||
|
else
|
||||||
|
rc = KernelError_Timeout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
} while (rc == KernelError_Canceled);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result waitN(s32* idx_out, Waiter* objects, size_t num_objects, u64 timeout) {
|
Result waitN(s32* idx_out, Waiter* objects, size_t num_objects, u64 timeout)
|
||||||
return _waitLoop((WaitImplFunc) &waitImpl, idx_out, (void*) objects, num_objects, timeout);
|
{
|
||||||
|
return _waitLoop((WaitImplFunc)waitImpl, idx_out, objects, num_objects, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result waitNHandle(s32* idx_out, Handle* handles, size_t num_handles, u64 timeout) {
|
Result waitNHandle(s32* idx_out, Handle* handles, size_t num_handles, u64 timeout)
|
||||||
return _waitLoop((WaitImplFunc) &svcWaitSynchronization, idx_out, (void*) handles, num_handles, timeout);
|
{
|
||||||
|
return _waitLoop((WaitImplFunc)svcWaitSynchronization, idx_out, handles, num_handles, timeout);
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ static inline void _waitableSignalAllListeners(Waitable* ww)
|
|||||||
WaitableNode* node = &ww->list;
|
WaitableNode* node = &ww->list;
|
||||||
WaitableNode* end = node;
|
WaitableNode* end = node;
|
||||||
|
|
||||||
while (node->next != end)
|
while (node->next != end) {
|
||||||
{
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
WaiterNode* w = (WaiterNode*) node;
|
WaiterNode* w = (WaiterNode*) node;
|
||||||
|
|
||||||
@ -26,10 +25,9 @@ static inline void _waitableSignalAllListeners(Waitable* ww)
|
|||||||
bool sent_idx = __atomic_compare_exchange_n(
|
bool sent_idx = __atomic_compare_exchange_n(
|
||||||
w->idx_out, &minus_one, w->idx, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
w->idx_out, &minus_one, w->idx, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
if (sent_idx) {
|
if (sent_idx)
|
||||||
svcCancelSynchronization(w->thread);
|
svcCancelSynchronization(w->thread);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _waiterNodeCreate(
|
static inline void _waiterNodeCreate(
|
||||||
|
Loading…
Reference in New Issue
Block a user