Repository: skyline-emu/skyline
File: app/src/main/cpp/skyline/common/utils.h (C/C++)

Code before:
    /**
     * @brief Returns the current time in nanoseconds
     * @return The current time in nanoseconds
     */
    inline i64 GetTimeNs() {
        u64 frequency;
        asm("MRS %0, CNTFRQ_EL0" : "=r"(frequency));
        u64 ticks;
        asm volatile("MRS %0, CNTVCT_EL0" : "=r"(ticks));
        return static_cast<i64>(((ticks / frequency) * constant::NsInSecond) + (((ticks % frequency) * constant::NsInSecond + (frequency / 2)) / frequency));
    }

    /**
     * @brief Returns the current time in arbitrary ticks
     * @return The current time in ticks
     */
    inline u64 GetTimeTicks() {
        u64 ticks;
        asm volatile("MRS %0, CNTVCT_EL0" : "=r"(ticks));
        return ticks;
    }

    /**
     * @brief A way to implicitly convert a pointer to uintptr_t and leave it unaffected if it isn't a pointer
     */
    template<typename T>
    constexpr T PointerValue(T item) {
        return item;
    }

    template<typename T>
    uintptr_t PointerValue(T *item) {
        return reinterpret_cast<uintptr_t>(item);
    }

    /**
     * @brief A way to implicitly convert an integral to a pointer, if the return type is a pointer
     */
    template<typename Return, typename T>
    constexpr Return ValuePointer(T item) {
        if constexpr (std::is_pointer<Return>::value)
            return reinterpret_cast<Return>(item);
        else
            return static_cast<Return>(item);
    }

    template<typename T>
    concept IsPointerOrUnsignedIntegral = (std::is_unsigned_v<T> && std::is_integral_v<T>) || std::is_pointer_v<T>;

    /**
     * @return The value aligned up to the next multiple

Review comment (suggestion):
Globals should be `CamelCase`, fix all usages of this too.
```suggestion
    inline const u64 ClockFrequency{detail::InitFrequency()}; //!< The system counter clock frequency in Hz
```

Code after:

    namespace detail {
        /**
         * @brief Retrieves the system counter clock frequency
         * @note Some devices report an incorrect value so they need special handling
         */
        inline u64 InitFrequency() {
            char buffer[PROP_VALUE_MAX];
            int len{__system_property_get("ro.product.board", buffer)};
            std::string_view board{buffer, static_cast<size_t>(len)};

            u64 frequency;
            if (board == "s5e9925")             // Exynos 2200
                frequency = 25600000;
            else if (board == "exynos2100")     // Exynos 2100
                frequency = 26000000;
            else if (board == "exynos9810")     // Exynos 9810
                frequency = 26000000;
            else
                asm volatile("MRS %0, CNTFRQ_EL0" : "=r"(frequency));

            return frequency;
        }
    }

    inline const u64 ClockFrequency{detail::InitFrequency()}; //!< The system counter clock frequency in Hz

    /**
     * @brief Returns the current time in nanoseconds
     * @return The current time in nanoseconds
     */
    inline i64 GetTimeNs() {
        u64 frequency{ClockFrequency};
        u64 ticks;
        asm volatile("MRS %0, CNTVCT_EL0" : "=r"(ticks));
        return static_cast<i64>(((ticks / frequency) * constant::NsInSecond) + (((ticks % frequency) * constant::NsInSecond + (frequency / 2)) / frequency));
    }

    /**
     * @brief Returns the current time in arbitrary ticks
     * @return The current time in ticks
     */
    inline u64 GetTimeTicks() {
        u64 ticks;
        asm volatile("MRS %0, CNTVCT_EL0" : "=r"(ticks));
        return ticks;
    }

    /**
     * @brief A way to implicitly convert a pointer to uintptr_t and leave it unaffected if it isn't a pointer
     */