From 2bf249ffe1450ee6e0d63f307092c08942ed02f8 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Wed, 6 Dec 2023 09:41:14 -0800 Subject: [PATCH] Avoid freezeing the core from LWIP under FreeRTOS (#1884) Avoid issues with interrupts and priority inversions and other deadlocks and use a SW based random generator for LWIP when under FreeRTOS. This means removing any overrides for sleep_until and the two get_rand_xx calls from the SDK, making things much saner. Related to #1883, #1872, and other random FreeRTOS lockups. --- README.md | 6 +- cores/rp2040/_freertos.cpp | 42 - cores/rp2040/_xoshiro.h | 1478 +++++++++++++++++++++++++++++ cores/rp2040/lwip_wrap.cpp | 15 + include/lwipopts.h | 4 +- lib/libpico.a | Bin 1225846 -> 1225846 bytes lib/libpicow-ipv6-btc-ble.a | Bin 7225952 -> 7225952 bytes lib/libpicow-ipv6-nobtc-noble.a | Bin 2580280 -> 2580280 bytes lib/libpicow-noipv6-btc-ble.a | Bin 6845734 -> 6845734 bytes lib/libpicow-noipv6-nobtc-noble.a | Bin 2200282 -> 2200282 bytes lib/platform_wrap.txt | 4 - tools/libpico/lwipopts.h | 4 +- 12 files changed, 1500 insertions(+), 53 deletions(-) create mode 100644 cores/rp2040/_xoshiro.h diff --git a/README.md b/README.md index d68dd9a..38772b6 100644 --- a/README.md +++ b/README.md @@ -252,14 +252,14 @@ If you want to contribute or have bugfixes, drop me a note at +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//---------------------------------------------------------------------------------------- + +# pragma once +# include +# include +# include +# include +# if __has_cpp_attribute(nodiscard) >= 201907L +# define XOSHIROCPP_NODISCARD_CXX20 [[nodiscard]] +# else +# define XOSHIROCPP_NODISCARD_CXX20 +# endif + +namespace XoshiroCpp { +// A default seed value for the generators +inline constexpr std::uint64_t DefaultSeed = 1234567890ULL; + +// Converts given uint32 value `i` into a 32-bit floating +// point value in the range of [0.0f, 1.0f) +template >* = nullptr> +[[nodiscard]] +inline constexpr float FloatFromBits(Uint32 i) noexcept; + +// Converts given uint64 value `i` into a 64-bit floating +// point value in the range of [0.0, 1.0) +template >* = nullptr> +[[nodiscard]] +inline constexpr double DoubleFromBits(Uint64 i) noexcept; + +// SplitMix64 +// Output: 64 bits +// Period: 2^64 +// Footprint: 8 bytes +// Original implementation: http://prng.di.unimi.it/splitmix64.c +class SplitMix64 { +public: + + using state_type = std::uint64_t; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr SplitMix64(state_type state = DefaultSeed) noexcept; + + constexpr result_type operator()() noexcept; + + template + [[nodiscard]] + constexpr std::array generateSeedSequence() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const SplitMix64& lhs, const SplitMix64& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const SplitMix64& lhs, const SplitMix64& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoshiro256+ +// Output: 64 bits +// Period: 2^256 - 1 +// Footprint: 32 bytes +// Original implementation: http://prng.di.unimi.it/xoshiro256plus.c +// Version: 1.0 +class Xoshiro256Plus { +public: + + using state_type = std::array; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro256Plus(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro256Plus(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^128 calls to operator(); it can be used to generate 2^128 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^192 calls to next(); it can be used to generate 2^64 starting points, + // from each of which jump() will generate 2^64 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoshiro256Plus& lhs, const Xoshiro256Plus& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoshiro256Plus& lhs, const Xoshiro256Plus& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoshiro256++ +// Output: 64 bits +// Period: 2^256 - 1 +// Footprint: 32 bytes +// Original implementation: http://prng.di.unimi.it/xoshiro256plusplus.c +// Version: 1.0 +class Xoshiro256PlusPlus { +public: + + using state_type = std::array; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro256PlusPlus(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro256PlusPlus(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^128 calls to next(); it can be used to generate 2^128 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^192 calls to next(); it can be used to generate 2^64 starting points, + // from each of which jump() will generate 2^64 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoshiro256PlusPlus& lhs, const Xoshiro256PlusPlus& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoshiro256PlusPlus& lhs, const Xoshiro256PlusPlus& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoshiro256** +// Output: 64 bits +// Period: 2^256 - 1 +// Footprint: 32 bytes +// Original implementation: http://prng.di.unimi.it/xoshiro256starstar.c +// Version: 1.0 +class Xoshiro256StarStar { +public: + + using state_type = std::array; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro256StarStar(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro256StarStar(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^128 calls to next(); it can be used to generate 2^128 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^192 calls to next(); it can be used to generate 2^64 starting points, + // from each of which jump() will generate 2^64 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoshiro256StarStar& lhs, const Xoshiro256StarStar& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoshiro256StarStar& lhs, const Xoshiro256StarStar& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoroshiro128+ +// Output: 64 bits +// Period: 2^128 - 1 +// Footprint: 16 bytes +// Original implementation: http://prng.di.unimi.it/xoroshiro128plus.c +// Version: 1.0 +class Xoroshiro128Plus { +public: + + using state_type = std::array; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoroshiro128Plus(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoroshiro128Plus(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^64 calls to next(); it can be used to generate 2^64 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^96 calls to next(); it can be used to generate 2^32 starting points, + // from each of which jump() will generate 2^32 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoroshiro128Plus& lhs, const Xoroshiro128Plus& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoroshiro128Plus& lhs, const Xoroshiro128Plus& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoroshiro128++ +// Output: 64 bits +// Period: 2^128 - 1 +// Footprint: 16 bytes +// Original implementation: http://prng.di.unimi.it/xoroshiro128plusplus.c +// Version: 1.0 +class Xoroshiro128PlusPlus { +public: + + using state_type = std::array; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoroshiro128PlusPlus(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoroshiro128PlusPlus(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^64 calls to next(); it can be used to generate 2^64 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^96 calls to next(); it can be used to generate 2^32 starting points, + // from each of which jump() will generate 2^32 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoroshiro128PlusPlus& lhs, const Xoroshiro128PlusPlus& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoroshiro128PlusPlus& lhs, const Xoroshiro128PlusPlus& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoroshiro128** +// Output: 64 bits +// Period: 2^128 - 1 +// Footprint: 16 bytes +// Original implementation: http://prng.di.unimi.it/xoroshiro128starstar.c +// Version: 1.0 +class Xoroshiro128StarStar { +public: + + using state_type = std::array; + using result_type = std::uint64_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoroshiro128StarStar(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoroshiro128StarStar(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^64 calls to next(); it can be used to generate 2^64 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^96 calls to next(); it can be used to generate 2^32 starting points, + // from each of which jump() will generate 2^32 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoroshiro128StarStar& lhs, const Xoroshiro128StarStar& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoroshiro128StarStar& lhs, const Xoroshiro128StarStar& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoshiro128+ +// Output: 32 bits +// Period: 2^128 - 1 +// Footprint: 16 bytes +// Original implementation: http://prng.di.unimi.it/xoshiro128plus.c +// Version: 1.0 +class Xoshiro128Plus { +public: + + using state_type = std::array; + using result_type = std::uint32_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro128Plus(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro128Plus(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^64 calls to next(); it can be used to generate 2^64 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^96 calls to next(); it can be used to generate 2^32 starting points, + // from each of which jump() will generate 2^32 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoshiro128Plus& lhs, const Xoshiro128Plus& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoshiro128Plus& lhs, const Xoshiro128Plus& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoshiro128++ +// Output: 32 bits +// Period: 2^128 - 1 +// Footprint: 16 bytes +// Original implementation: http://prng.di.unimi.it/xoshiro128plusplus.c +// Version: 1.0 +class Xoshiro128PlusPlus { +public: + + using state_type = std::array; + using result_type = std::uint32_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro128PlusPlus(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro128PlusPlus(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^64 calls to next(); it can be used to generate 2^64 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^96 calls to next(); it can be used to generate 2^32 starting points, + // from each of which jump() will generate 2^32 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoshiro128PlusPlus& lhs, const Xoshiro128PlusPlus& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoshiro128PlusPlus& lhs, const Xoshiro128PlusPlus& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; + +// xoshiro128** +// Output: 32 bits +// Period: 2^128 - 1 +// Footprint: 16 bytes +// Original implementation: http://prng.di.unimi.it/xoshiro128starstar.c +// Version: 1.1 +class Xoshiro128StarStar { +public: + + using state_type = std::array; + using result_type = std::uint32_t; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro128StarStar(std::uint64_t seed = DefaultSeed) noexcept; + + XOSHIROCPP_NODISCARD_CXX20 + explicit constexpr Xoshiro128StarStar(state_type state) noexcept; + + constexpr result_type operator()() noexcept; + + // This is the jump function for the generator. It is equivalent + // to 2^64 calls to next(); it can be used to generate 2^64 + // non-overlapping subsequences for parallel computations. + constexpr void jump() noexcept; + + // This is the long-jump function for the generator. It is equivalent to + // 2^96 calls to next(); it can be used to generate 2^32 starting points, + // from each of which jump() will generate 2^32 non-overlapping + // subsequences for parallel distributed computations. + constexpr void longJump() noexcept; + + [[nodiscard]] + static constexpr result_type min() noexcept; + + [[nodiscard]] + static constexpr result_type max() noexcept; + + [[nodiscard]] + constexpr state_type serialize() const noexcept; + + constexpr void deserialize(state_type state) noexcept; + + [[nodiscard]] + friend bool operator ==(const Xoshiro128StarStar& lhs, const Xoshiro128StarStar& rhs) noexcept { + return (lhs.m_state == rhs.m_state); + } + + [[nodiscard]] + friend bool operator !=(const Xoshiro128StarStar& lhs, const Xoshiro128StarStar& rhs) noexcept { + return (lhs.m_state != rhs.m_state); + } + +private: + + state_type m_state; +}; +} + +//////////////////////////////////////////////////////////////// +namespace XoshiroCpp { +#if 0 +template >*> +inline constexpr float FloatFromBits(const Uint32 i) noexcept { + return (i >> 8) * 0x1.0p - 24f; +} + +template >*> +inline constexpr double DoubleFromBits(const Uint64 i) noexcept { + return (i >> 11) * 0x1.0p - 53; +} +#endif + +namespace detail { +[[nodiscard]] +static constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept { + return (x << s) | (x >> (64 - s)); +} + +[[nodiscard]] +static constexpr std::uint32_t RotL(const std::uint32_t x, const int s) noexcept { + return (x << s) | (x >> (32 - s)); +} +} +//////////////////////////////////////////////////////////////// +// +// SplitMix64 +// +inline constexpr SplitMix64::SplitMix64(const state_type state) noexcept + : m_state(state) {} + +inline constexpr SplitMix64::result_type SplitMix64::operator()() noexcept { + std::uint64_t z = (m_state += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); +} + +template +inline constexpr std::array SplitMix64::generateSeedSequence() noexcept { + std::array seeds = {}; + + for (auto& seed : seeds) { + seed = operator()(); + } + + return seeds; +} + +inline constexpr SplitMix64::result_type SplitMix64::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr SplitMix64::result_type SplitMix64::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr SplitMix64::state_type SplitMix64::serialize() const noexcept { + return m_state; +} + +inline constexpr void SplitMix64::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoshiro256+ +// +inline constexpr Xoshiro256Plus::Xoshiro256Plus(const std::uint64_t seed) noexcept + : m_state(SplitMix64 { + seed +} .generateSeedSequence<4>()) {} + +inline constexpr Xoshiro256Plus::Xoshiro256Plus(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoshiro256Plus::result_type Xoshiro256Plus::operator()() noexcept { + const std::uint64_t result = m_state[0] + m_state[3]; + const std::uint64_t t = m_state[1] << 17; + m_state[2] ^= m_state[0]; + m_state[3] ^= m_state[1]; + m_state[1] ^= m_state[2]; + m_state[0] ^= m_state[3]; + m_state[2] ^= t; + m_state[3] = detail::RotL(m_state[3], 45); + return result; +} + +inline constexpr void Xoshiro256Plus::jump() noexcept { + constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::uint64_t s2 = 0; + std::uint64_t s3 = 0; + + for (std::uint64_t jump : JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr void Xoshiro256Plus::longJump() noexcept { + constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::uint64_t s2 = 0; + std::uint64_t s3 = 0; + + for (std::uint64_t jump : LONG_JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr Xoshiro256Plus::result_type Xoshiro256Plus::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoshiro256Plus::result_type Xoshiro256Plus::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoshiro256Plus::state_type Xoshiro256Plus::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoshiro256Plus::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoshiro256++ +// +inline constexpr Xoshiro256PlusPlus::Xoshiro256PlusPlus(const std::uint64_t seed) noexcept + : m_state(SplitMix64 { + seed +} .generateSeedSequence<4>()) {} + +inline constexpr Xoshiro256PlusPlus::Xoshiro256PlusPlus(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoshiro256PlusPlus::result_type Xoshiro256PlusPlus::operator()() noexcept { + const std::uint64_t result = detail::RotL(m_state[0] + m_state[3], 23) + m_state[0]; + const std::uint64_t t = m_state[1] << 17; + m_state[2] ^= m_state[0]; + m_state[3] ^= m_state[1]; + m_state[1] ^= m_state[2]; + m_state[0] ^= m_state[3]; + m_state[2] ^= t; + m_state[3] = detail::RotL(m_state[3], 45); + return result; +} + +inline constexpr void Xoshiro256PlusPlus::jump() noexcept { + constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::uint64_t s2 = 0; + std::uint64_t s3 = 0; + + for (std::uint64_t jump : JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr void Xoshiro256PlusPlus::longJump() noexcept { + constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::uint64_t s2 = 0; + std::uint64_t s3 = 0; + + for (std::uint64_t jump : LONG_JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr Xoshiro256PlusPlus::result_type Xoshiro256PlusPlus::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoshiro256PlusPlus::result_type Xoshiro256PlusPlus::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoshiro256PlusPlus::state_type Xoshiro256PlusPlus::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoshiro256PlusPlus::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoshiro256** +// +inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(const std::uint64_t seed) noexcept + : m_state(SplitMix64 { + seed +} .generateSeedSequence<4>()) {} + +inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoshiro256StarStar::result_type Xoshiro256StarStar::operator()() noexcept { + const std::uint64_t result = detail::RotL(m_state[1] * 5, 7) * 9; + const std::uint64_t t = m_state[1] << 17; + m_state[2] ^= m_state[0]; + m_state[3] ^= m_state[1]; + m_state[1] ^= m_state[2]; + m_state[0] ^= m_state[3]; + m_state[2] ^= t; + m_state[3] = detail::RotL(m_state[3], 45); + return result; +} + +inline constexpr void Xoshiro256StarStar::jump() noexcept { + constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::uint64_t s2 = 0; + std::uint64_t s3 = 0; + + for (std::uint64_t jump : JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr void Xoshiro256StarStar::longJump() noexcept { + constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::uint64_t s2 = 0; + std::uint64_t s3 = 0; + + for (std::uint64_t jump : LONG_JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr Xoshiro256StarStar::result_type Xoshiro256StarStar::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoshiro256StarStar::result_type Xoshiro256StarStar::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoshiro256StarStar::state_type Xoshiro256StarStar::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoshiro256StarStar::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoroshiro128+ +// +inline constexpr Xoroshiro128Plus::Xoroshiro128Plus(const std::uint64_t seed) noexcept + : m_state(SplitMix64 { + seed +} .generateSeedSequence<2>()) {} + +inline constexpr Xoroshiro128Plus::Xoroshiro128Plus(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoroshiro128Plus::result_type Xoroshiro128Plus::operator()() noexcept { + const std::uint64_t s0 = m_state[0]; + std::uint64_t s1 = m_state[1]; + const std::uint64_t result = s0 + s1; + s1 ^= s0; + m_state[0] = detail::RotL(s0, 24) ^ s1 ^ (s1 << 16); + m_state[1] = detail::RotL(s1, 37); + return result; +} + +inline constexpr void Xoroshiro128Plus::jump() noexcept { + constexpr std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + + for (std::uint64_t jump : JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; +} + +inline constexpr void Xoroshiro128Plus::longJump() noexcept { + constexpr std::uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + + for (std::uint64_t jump : LONG_JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; +} + +inline constexpr Xoroshiro128Plus::result_type Xoroshiro128Plus::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoroshiro128Plus::result_type Xoroshiro128Plus::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoroshiro128Plus::state_type Xoroshiro128Plus::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoroshiro128Plus::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoroshiro128++ +// +inline constexpr Xoroshiro128PlusPlus::Xoroshiro128PlusPlus(const std::uint64_t seed) noexcept + : m_state(SplitMix64 { + seed +} .generateSeedSequence<2>()) {} + +inline constexpr Xoroshiro128PlusPlus::Xoroshiro128PlusPlus(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoroshiro128PlusPlus::result_type Xoroshiro128PlusPlus::operator()() noexcept { + const std::uint64_t s0 = m_state[0]; + std::uint64_t s1 = m_state[1]; + const std::uint64_t result = detail::RotL(s0 + s1, 17) + s0; + s1 ^= s0; + m_state[0] = detail::RotL(s0, 49) ^ s1 ^ (s1 << 21); + m_state[1] = detail::RotL(s1, 28); + return result; +} + +inline constexpr void Xoroshiro128PlusPlus::jump() noexcept { + constexpr std::uint64_t JUMP[] = { 0x2bd7a6a6e99c2ddc, 0x0992ccaf6a6fca05 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + + for (std::uint64_t jump : JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; +} + +inline constexpr void Xoroshiro128PlusPlus::longJump() noexcept { + constexpr std::uint64_t LONG_JUMP[] = { 0x360fd5f2cf8d5d99, 0x9c6e6877736c46e3 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + + for (std::uint64_t jump : LONG_JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; +} + +inline constexpr Xoroshiro128PlusPlus::result_type Xoroshiro128PlusPlus::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoroshiro128PlusPlus::result_type Xoroshiro128PlusPlus::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoroshiro128PlusPlus::state_type Xoroshiro128PlusPlus::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoroshiro128PlusPlus::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoroshiro128** +// +inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(const std::uint64_t seed) noexcept + : m_state(SplitMix64 { + seed +} .generateSeedSequence<2>()) {} + +inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoroshiro128StarStar::result_type Xoroshiro128StarStar::operator()() noexcept { + const std::uint64_t s0 = m_state[0]; + std::uint64_t s1 = m_state[1]; + const std::uint64_t result = detail::RotL(s0 * 5, 7) * 9; + s1 ^= s0; + m_state[0] = detail::RotL(s0, 24) ^ s1 ^ (s1 << 16); + m_state[1] = detail::RotL(s1, 37); + return result; +} + +inline constexpr void Xoroshiro128StarStar::jump() noexcept { + constexpr std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + + for (std::uint64_t jump : JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; +} + +inline constexpr void Xoroshiro128StarStar::longJump() noexcept { + constexpr std::uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 }; + + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + + for (std::uint64_t jump : LONG_JUMP) { + for (int b = 0; b < 64; ++b) { + if (jump & UINT64_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; +} + +inline constexpr Xoroshiro128StarStar::result_type Xoroshiro128StarStar::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoroshiro128StarStar::result_type Xoroshiro128StarStar::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoroshiro128StarStar::state_type Xoroshiro128StarStar::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoroshiro128StarStar::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoshiro128+ +// +inline constexpr Xoshiro128Plus::Xoshiro128Plus(const std::uint64_t seed) noexcept + : m_state() { + SplitMix64 splitmix{ seed }; + + for (auto& state : m_state) { + state = static_cast(splitmix()); + } +} + +inline constexpr Xoshiro128Plus::Xoshiro128Plus(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoshiro128Plus::result_type Xoshiro128Plus::operator()() noexcept { + const std::uint32_t result = m_state[0] + m_state[3]; + const std::uint32_t t = m_state[1] << 9; + m_state[2] ^= m_state[0]; + m_state[3] ^= m_state[1]; + m_state[1] ^= m_state[2]; + m_state[0] ^= m_state[3]; + m_state[2] ^= t; + m_state[3] = detail::RotL(m_state[3], 11); + return result; +} + +inline constexpr void Xoshiro128Plus::jump() noexcept { + constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b }; + + std::uint32_t s0 = 0; + std::uint32_t s1 = 0; + std::uint32_t s2 = 0; + std::uint32_t s3 = 0; + + for (std::uint32_t jump : JUMP) { + for (int b = 0; b < 32; ++b) { + if (jump & UINT32_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr void Xoshiro128Plus::longJump() noexcept { + constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 }; + + std::uint32_t s0 = 0; + std::uint32_t s1 = 0; + std::uint32_t s2 = 0; + std::uint32_t s3 = 0; + + for (std::uint32_t jump : LONG_JUMP) { + for (int b = 0; b < 32; ++b) { + if (jump & UINT32_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr Xoshiro128Plus::result_type Xoshiro128Plus::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoshiro128Plus::result_type Xoshiro128Plus::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoshiro128Plus::state_type Xoshiro128Plus::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoshiro128Plus::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoshiro128++ +// +inline constexpr Xoshiro128PlusPlus::Xoshiro128PlusPlus(const std::uint64_t seed) noexcept + : m_state() { + SplitMix64 splitmix{ seed }; + + for (auto& state : m_state) { + state = static_cast(splitmix()); + } +} + +inline constexpr Xoshiro128PlusPlus::Xoshiro128PlusPlus(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoshiro128PlusPlus::result_type Xoshiro128PlusPlus::operator()() noexcept { + const std::uint32_t result = detail::RotL(m_state[0] + m_state[3], 7) + m_state[0]; + const std::uint32_t t = m_state[1] << 9; + m_state[2] ^= m_state[0]; + m_state[3] ^= m_state[1]; + m_state[1] ^= m_state[2]; + m_state[0] ^= m_state[3]; + m_state[2] ^= t; + m_state[3] = detail::RotL(m_state[3], 11); + return result; +} + +inline constexpr void Xoshiro128PlusPlus::jump() noexcept { + constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b }; + + std::uint32_t s0 = 0; + std::uint32_t s1 = 0; + std::uint32_t s2 = 0; + std::uint32_t s3 = 0; + + for (std::uint32_t jump : JUMP) { + for (int b = 0; b < 32; ++b) { + if (jump & UINT32_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr void Xoshiro128PlusPlus::longJump() noexcept { + constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 }; + + std::uint32_t s0 = 0; + std::uint32_t s1 = 0; + std::uint32_t s2 = 0; + std::uint32_t s3 = 0; + + for (std::uint32_t jump : LONG_JUMP) { + for (int b = 0; b < 32; ++b) { + if (jump & UINT32_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr Xoshiro128PlusPlus::result_type Xoshiro128PlusPlus::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoshiro128PlusPlus::result_type Xoshiro128PlusPlus::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoshiro128PlusPlus::state_type Xoshiro128PlusPlus::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoshiro128PlusPlus::deserialize(const state_type state) noexcept { + m_state = state; +} + +//////////////////////////////////////////////////////////////// +// +// xoshiro128** +// +inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(const std::uint64_t seed) noexcept + : m_state() { + SplitMix64 splitmix{ seed }; + + for (auto& state : m_state) { + state = static_cast(splitmix()); + } +} + +inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(const state_type state) noexcept + : m_state(state) {} + +inline constexpr Xoshiro128StarStar::result_type Xoshiro128StarStar::operator()() noexcept { + const std::uint32_t result = detail::RotL(m_state[1] * 5, 7) * 9; + const std::uint32_t t = m_state[1] << 9; + m_state[2] ^= m_state[0]; + m_state[3] ^= m_state[1]; + m_state[1] ^= m_state[2]; + m_state[0] ^= m_state[3]; + m_state[2] ^= t; + m_state[3] = detail::RotL(m_state[3], 11); + return result; +} + +inline constexpr void Xoshiro128StarStar::jump() noexcept { + constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b }; + + std::uint32_t s0 = 0; + std::uint32_t s1 = 0; + std::uint32_t s2 = 0; + std::uint32_t s3 = 0; + + for (std::uint32_t jump : JUMP) { + for (int b = 0; b < 32; ++b) { + if (jump & UINT32_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr void Xoshiro128StarStar::longJump() noexcept { + constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 }; + + std::uint32_t s0 = 0; + std::uint32_t s1 = 0; + std::uint32_t s2 = 0; + std::uint32_t s3 = 0; + + for (std::uint32_t jump : LONG_JUMP) { + for (int b = 0; b < 32; ++b) { + if (jump & UINT32_C(1) << b) { + s0 ^= m_state[0]; + s1 ^= m_state[1]; + s2 ^= m_state[2]; + s3 ^= m_state[3]; + } + operator()(); + } + } + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; +} + +inline constexpr Xoshiro128StarStar::result_type Xoshiro128StarStar::min() noexcept { + return std::numeric_limits::lowest(); +} + +inline constexpr Xoshiro128StarStar::result_type Xoshiro128StarStar::max() noexcept { + return std::numeric_limits::max(); +} + +inline constexpr Xoshiro128StarStar::state_type Xoshiro128StarStar::serialize() const noexcept { + return m_state; +} + +inline constexpr void Xoshiro128StarStar::deserialize(const state_type state) noexcept { + m_state = state; +} +} diff --git a/cores/rp2040/lwip_wrap.cpp b/cores/rp2040/lwip_wrap.cpp index a1390b1..6de14a8 100644 --- a/cores/rp2040/lwip_wrap.cpp +++ b/cores/rp2040/lwip_wrap.cpp @@ -29,6 +29,7 @@ #include #include #include +#include "_xoshiro.h" extern void ethernet_arch_lwip_begin() __attribute__((weak)); extern void ethernet_arch_lwip_end() __attribute__((weak)); @@ -68,11 +69,25 @@ public: extern "C" { + static XoshiroCpp::Xoshiro256PlusPlus *_lwip_rng = nullptr; + // Random number generator for LWIP. Bare metal, use the HW. FreeRTOS, use xoshiro generator to avoid needing to freeze the other core + unsigned long __lwip_rand() { + if (__isFreeRTOS) { + return (unsigned long)(*_lwip_rng)(); + } else { + return get_rand_32(); + } + } + + // Avoid calling lwip_init multiple times extern void __real_lwip_init(); void __wrap_lwip_init() { static bool initted = false; if (!initted) { + if (__isFreeRTOS) { + _lwip_rng = new XoshiroCpp::Xoshiro256PlusPlus(rp2040.getCycleCount()); + } __real_lwip_init(); initted = true; } diff --git a/include/lwipopts.h b/include/lwipopts.h index 0dc0ed6..d4981e1 100644 --- a/include/lwipopts.h +++ b/include/lwipopts.h @@ -13,8 +13,8 @@ extern void interrupts(); #define SYS_ARCH_PROTECT(lev) noInterrupts #define SYS_ARCH_UNPROTECT(lev) interrupts -extern unsigned long get_rand_32(void); -#define LWIP_RAND() get_rand_32() +extern unsigned long __lwip_rand(void); +#define LWIP_RAND() __lwip_rand() // Common settings used in most of the pico_w examples // (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details) diff --git a/lib/libpico.a b/lib/libpico.a index df7730a9f34960ed636225df668c072964fe5369..60a145f71c3e2bd89390798e344a6a2af2728767 100644 GIT binary patch delta 1455 zcmZXUT}TvB6vx?**&Utz8nd0LEG3nqw$j=ila<`XNYijFK_BvCX+bIzB^1mcAEbJa zl3HpW6q@iMDGF`X6BJZN1QC?rL(+pjg!#~ekQivN-MJHcuG{1PcmLyn`t-g%1ja0!4{{F03r?C_biOoyHbCFTM-bE zSP5c1oWB$qXwSG0yBXaz%L!*t-*4n)7|FL)$|pH|k9ltzgWR|L$`V2vd}u6VwIq#IEM|=Okr{;~volZqm$7|+=GS?~ zNoN(~gfbD~Jm)|vOW^@*E$PuhiLA1UCy~7^i655 za{Oc!vQ-i!Yh6u0(L#HDHR#Scj1066_Y)gx<419++Z|^+5%r5PXkT}SSSN{;r#^X9 zmeG%R!0vIhGbxF28%$jG+-9A0O08EsWs{qovbq=+*J1jg_>jXBAQg;m3MZHA&Kl?p qigoEHKu(6!U<`g#iB&A5#YQ4xRU2~=sq5Ek)T;hUnC!`#IrbObLYU(K delta 1455 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

E{kC;L#9rIwEjBLUl;L8iB`oREBHS49o=I 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 F{|8bmr$+z) diff --git a/lib/libpicow-ipv6-nobtc-noble.a b/lib/libpicow-ipv6-nobtc-noble.a index 2591056f9ecde3e55d9dd5d33ba15fa6b0ada042..42a064f763911e23bf093dae1dd9211143622946 100644 GIT binary patch delta 10301 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 RT}@~q;+;iyj7=LQ{~yMue69ch diff --git a/lib/libpicow-noipv6-btc-ble.a b/lib/libpicow-noipv6-btc-ble.a index 5731d427c9cbfdb708da36e3d37f270f4b847569..93b3f3d2cc7c1f952b3e7e390952a45310571ebc 100644 GIT binary patch delta 6958 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 C$2HFY delta 6971 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 QDv{hwP*3@0(v$lC0R{ZCfdBvi delta 4912 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 diff --git a/lib/platform_wrap.txt b/lib/platform_wrap.txt index c805bb3..eef50cf 100644 --- a/lib/platform_wrap.txt +++ b/lib/platform_wrap.txt @@ -209,7 +209,3 @@ -Wl,--wrap=cyw43_tcpip_link_status -Wl,--wrap=cyw43_cb_tcpip_init -Wl,--wrap=cyw43_cb_tcpip_deinit - --Wl,--wrap=get_rand_64 --Wl,--wrap=get_rand_32 --Wl,--wrap=sleep_until diff --git a/tools/libpico/lwipopts.h b/tools/libpico/lwipopts.h index 0dc0ed6..d4981e1 100644 --- a/tools/libpico/lwipopts.h +++ b/tools/libpico/lwipopts.h @@ -13,8 +13,8 @@ extern void interrupts(); #define SYS_ARCH_PROTECT(lev) noInterrupts #define SYS_ARCH_UNPROTECT(lev) interrupts -extern unsigned long get_rand_32(void); -#define LWIP_RAND() get_rand_32() +extern unsigned long __lwip_rand(void); +#define LWIP_RAND() __lwip_rand() // Common settings used in most of the pico_w examples // (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)