From 9144d78031ac0b137762b4a3036dab6215e33c83 Mon Sep 17 00:00:00 2001 From: fincs Date: Fri, 14 Dec 2018 13:57:44 +0100 Subject: [PATCH] Stylefixes, part 1 --- nx/include/switch/kernel/uevent.h | 16 ++- nx/include/switch/kernel/utimer.h | 18 ++-- nx/include/switch/kernel/wait.h | 41 ++++---- nx/source/kernel/uevent.c | 19 +--- nx/source/kernel/utimer.c | 24 ++--- nx/source/kernel/wait.c | 163 +++++++++++++----------------- nx/source/kernel/wait.h | 6 +- 7 files changed, 137 insertions(+), 150 deletions(-) diff --git a/nx/include/switch/kernel/uevent.h b/nx/include/switch/kernel/uevent.h index db77f918..4ea6d4b9 100644 --- a/nx/include/switch/kernel/uevent.h +++ b/nx/include/switch/kernel/uevent.h @@ -1,29 +1,35 @@ -// Copyright 2018 plutoo +/** + * @file uevent.h + * @brief User-mode event synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ #pragma once -#include "../kernel/wait.h" +#include "wait.h" typedef struct UEvent UEvent; -struct UEvent -{ +struct UEvent { Waitable waitable; bool signal; bool auto_clear; }; /** - * @brief Creates a usermode event. + * @brief Creates a user-mode event. * @param[out] e UEvent 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(UEvent* e, bool auto_clear); + /** * @brief Clears the event signal. * @param[in] e UEvent object. */ void ueventClear(UEvent* e); + /** * @brief Signals the event. * @param[in] e UEvent object. diff --git a/nx/include/switch/kernel/utimer.h b/nx/include/switch/kernel/utimer.h index 165d978e..621ee3b6 100644 --- a/nx/include/switch/kernel/utimer.h +++ b/nx/include/switch/kernel/utimer.h @@ -1,16 +1,20 @@ -// Copyright 2018 plutoo +/** + * @file uevent.h + * @brief User-mode timer synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ #pragma once -#include "../kernel/wait.h" +#include "wait.h" typedef struct UTimer UTimer; typedef enum { TimerType_OneShot, - TimerType_Repeating + TimerType_Repeating, } TimerType; -struct UTimer -{ +struct UTimer { Waitable waitable; TimerType type; 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[in] interval Interval (in nanoseconds). * @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. */ void utimerCreate(UTimer* t, u64 interval, TimerType type); + /** * @brief Starts the timer. * @param[in] t UTimer object. */ void utimerStart(UTimer* t); + /** * @brief Stops the timer. * @param[in] t UTimer object. diff --git a/nx/include/switch/kernel/wait.h b/nx/include/switch/kernel/wait.h index d9e0bdc2..0d6cf84f 100644 --- a/nx/include/switch/kernel/wait.h +++ b/nx/include/switch/kernel/wait.h @@ -1,8 +1,13 @@ -// Copyright 2018 plutoo +/** + * @file wait.h + * @brief User mode synchronization primitive waiting operations. + * @author plutoo + * @copyright libnx Authors + */ #pragma once -#include "../kernel/mutex.h" -#include "../kernel/event.h" -#include "../kernel/thread.h" +#include "mutex.h" +#include "event.h" +#include "thread.h" // Implementation details. typedef struct UEvent UEvent; @@ -10,14 +15,13 @@ typedef struct UTimer UTimer; typedef enum { WaiterNodeType_Event, - WaiterNodeType_Timer + WaiterNodeType_Timer, } WaiterNodeType; typedef struct Waitable Waitable; typedef struct WaitableNode WaitableNode; -struct WaitableNode -{ +struct WaitableNode { WaitableNode* prev; WaitableNode* next; }; @@ -35,8 +39,7 @@ typedef struct { size_t* idx_out; } WaiterNode; -struct Waitable -{ +struct Waitable { WaitableNode list; Mutex mutex; }; @@ -58,7 +61,7 @@ typedef struct { }; } Waiter; -/// Creates a waiter for a kernelmode handle. +/// Creates a waiter for a kernel-mode handle. static inline Waiter waiterForHandle(Handle h) { Waiter wait_obj; @@ -67,7 +70,7 @@ static inline Waiter waiterForHandle(Handle h) return wait_obj; } -/// Creates a waiter for a usermode timer. +/// Creates a waiter for a user-mode timer. static inline Waiter waiterForUTimer(UTimer* t) { Waiter wait_obj; @@ -76,7 +79,7 @@ static inline Waiter waiterForUTimer(UTimer* t) return wait_obj; } -/// Creates a waiter for a usermode event. +/// Creates a waiter for a user-mode event. static inline Waiter waiterForUEvent(UEvent* e) { Waiter wait_obj; @@ -85,13 +88,15 @@ static inline Waiter waiterForUEvent(UEvent* e) return wait_obj; } -/// Creates a waiter for a kernelmode event. -static inline Waiter waiterForEvent(Event* e) { +/// Creates a waiter for a kernel-mode event. +static inline Waiter waiterForEvent(Event* e) +{ return waiterForHandle(e->revent); } /// Creates a waiter for a thread exit. -static inline Waiter waiterForThreadExit(Thread* t) { +static inline Waiter waiterForThreadExit(Thread* t) +{ 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] timeout Timeout (in nanoseconds). */ -static inline Result waitSingle(Waiter w, u64 timeout) { +static inline Result waitSingle(Waiter w, u64 timeout) +{ s32 idx; 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] timeout Timeout (in nanoseconds). */ -static inline Result waitSingleHandle(Handle h, u64 timeout) { +static inline Result waitSingleHandle(Handle h, u64 timeout) +{ s32 idx; return waitMultiHandle(&idx, timeout, h); } diff --git a/nx/source/kernel/uevent.c b/nx/source/kernel/uevent.c index b384b0e3..1032a1f3 100644 --- a/nx/source/kernel/uevent.c +++ b/nx/source/kernel/uevent.c @@ -31,9 +31,8 @@ void ueventSignal(UEvent* e) void _ueventTryAutoClear(UEvent* e) { mutexLock(&e->waitable.mutex); - if (e->auto_clear) { + if (e->auto_clear) e->signal = false; - } 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); bool signalled = e->signal; - bool ret; - if (signalled) - { - if (e->auto_clear) { + if (signalled) { + if (e->auto_clear) e->signal = false; - } - ret = false; - } - else - { + } else _waiterNodeAddToWaitable(w, &e->waitable); - ret = true; - } mutexUnlock(&e->waitable.mutex); - return ret; + return !signalled; } diff --git a/nx/source/kernel/utimer.c b/nx/source/kernel/utimer.c index d2a1debd..0e1d17b0 100644 --- a/nx/source/kernel/utimer.c +++ b/nx/source/kernel/utimer.c @@ -20,8 +20,7 @@ void utimerStart(UTimer* t) { mutexLock(&t->waitable.mutex); - if (t->next_tick == STOPPED) - { + if (t->next_tick == STOPPED) { u64 new_tick = armGetSystemTick() + t->interval; t->next_tick = new_tick; _waitableSignalAllListeners(&t->waitable); @@ -34,8 +33,7 @@ void utimerStop(UTimer* t) { mutexLock(&t->waitable.mutex); - if (t->next_tick != STOPPED) - { + if (t->next_tick != STOPPED) { t->next_tick = STOPPED; _waitableSignalAllListeners(&t->waitable); } @@ -47,19 +45,17 @@ void _utimerRecalculate(UTimer* t, u64 old_tick) { mutexLock(&t->waitable.mutex); - if (t->next_tick == old_tick) - { + if (t->next_tick == old_tick) { u64 interval = t->interval; u64 new_tick = 0; - switch (t->type) - { - case TimerType_OneShot: - new_tick = STOPPED; - break; - case TimerType_Repeating: - new_tick = old_tick + ((svcGetSystemTick() - old_tick + interval - 1)/interval)*interval; - break; + switch (t->type) { + case TimerType_OneShot: + new_tick = STOPPED; + break; + case TimerType_Repeating: + new_tick = old_tick + ((svcGetSystemTick() - old_tick + interval - 1)/interval)*interval; + break; } t->next_tick = new_tick; diff --git a/nx/source/kernel/wait.c b/nx/source/kernel/wait.c index c967a070..d4b8b11c 100644 --- a/nx/source/kernel/wait.c +++ b/nx/source/kernel/wait.c @@ -37,69 +37,61 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti s32 end_tick_idx = -1; size_t i; - for (i=0; itype) - { - case WaiterType_UTimer: + switch (obj->type) { + case WaiterType_UTimer: + timer_tick = _utimerGetNextTick(obj->timer); - timer_tick = _utimerGetNextTick(obj->timer); + // Skip timer if stopped. + if (timer_tick != 0) { + // If the timer already signalled, we're done. + if (timer_tick < cur_tick) { + _utimerRecalculate(obj->timer, timer_tick); - // Skip timer if stopped. - if (timer_tick != 0) - { - // If the timer already signalled, we're done. - if (timer_tick < cur_tick) - { - _utimerRecalculate(obj->timer, timer_tick); + *idx_out = i; + rc = 0; + goto clean_up; + } + // Override the user-supplied timeout if timer would fire before that. + if ((timer_tick - cur_tick) < end_tick) { + end_tick = timer_tick - cur_tick; + end_tick_idx = i; + } + } + + // Always add a listener on the timer, + // If the timer is started/stopped we want to detect that. + _utimerAddListener( + obj->timer, &waiters[num_waiters], num_waiters, &triggered_idx, + own_thread_handle); + + num_waiters++; + break; + + case WaiterType_UEvent: + // Try to add a listener to the event, if it hasn't already signalled. + added = _ueventAddListener( + obj->event, &waiters[num_waiters], num_waiters, &triggered_idx, + own_thread_handle); + + // If the event already happened, we're done. + if (!added) { *idx_out = i; rc = 0; goto clean_up; } - // Override the user-supplied timeout if timer would fire before that. - if ((timer_tick - cur_tick) < end_tick) - { - end_tick = timer_tick - cur_tick; - end_tick_idx = i; - } - } + // If the event hasn't signalled, we added a listener. + num_waiters++; + break; - // Always add a listener on the timer, - // If the timer is started/stopped we want to detect that. - _utimerAddListener( - obj->timer, &waiters[num_waiters], num_waiters, &triggered_idx, - own_thread_handle); - - num_waiters++; - break; - - case WaiterType_UEvent: - - // Try to add a listener to the event, if it hasn't already signalled. - added = _ueventAddListener( - obj->event, &waiters[num_waiters], num_waiters, &triggered_idx, - own_thread_handle); - - // If the event already happened, we're done. - if (!added) - { - *idx_out = i; - rc = 0; - goto clean_up; - } - - // If the event hasn't signalled, we added a listener. - num_waiters++; - break; - - case WaiterType_Handle: - break; + case WaiterType_Handle: + break; } // Add handle for i:th object. @@ -110,21 +102,17 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti // Do the actual syscall. 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 (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); *idx_out = end_tick_idx; 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. // This only happens if user for some reason manually does a svcCancelSynchronization. // Check just in case. @@ -133,65 +121,60 @@ static Result waitImpl(s32* idx_out, Waiter* objects, size_t num_objects, u64 ti // An event was signalled, or a timer was updated. // So.. which is it? - switch (waiters[triggered_idx].type) - { - case WaiterNodeType_Event: - _ueventTryAutoClear(waiters[triggered_idx].parent_event); + switch (waiters[triggered_idx].type) { + case WaiterNodeType_Event: + _ueventTryAutoClear(waiters[triggered_idx].parent_event); - *idx_out = triggered_idx; - rc = 0; - break; + *idx_out = triggered_idx; + rc = 0; + break; - case WaiterNodeType_Timer: - rc = KernelError_Canceled; - break; + case WaiterNodeType_Timer: + rc = KernelError_Canceled; + break; } } clean_up: - // Remove listeners. - for (i=0; i= timeout) { - return KernelError_Timeout; - } - - timeout -= time_spent; + if (time_spent < timeout) + timeout -= time_spent; + else + rc = KernelError_Timeout; } } - else { - return rc; - } - } + } while (rc == KernelError_Canceled); + + return rc; } -Result waitN(s32* idx_out, Waiter* objects, size_t num_objects, u64 timeout) { - return _waitLoop((WaitImplFunc) &waitImpl, idx_out, (void*) objects, num_objects, timeout); +Result waitN(s32* idx_out, Waiter* objects, size_t num_objects, u64 timeout) +{ + return _waitLoop((WaitImplFunc)waitImpl, idx_out, objects, num_objects, 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); +Result waitNHandle(s32* idx_out, Handle* handles, size_t num_handles, u64 timeout) +{ + return _waitLoop((WaitImplFunc)svcWaitSynchronization, idx_out, handles, num_handles, timeout); } diff --git a/nx/source/kernel/wait.h b/nx/source/kernel/wait.h index abe2734b..29553199 100644 --- a/nx/source/kernel/wait.h +++ b/nx/source/kernel/wait.h @@ -15,8 +15,7 @@ static inline void _waitableSignalAllListeners(Waitable* ww) WaitableNode* node = &ww->list; WaitableNode* end = node; - while (node->next != end) - { + while (node->next != end) { node = node->next; WaiterNode* w = (WaiterNode*) node; @@ -26,9 +25,8 @@ static inline void _waitableSignalAllListeners(Waitable* ww) bool sent_idx = __atomic_compare_exchange_n( w->idx_out, &minus_one, w->idx, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - if (sent_idx) { + if (sent_idx) svcCancelSynchronization(w->thread); - } } }