diff options
Diffstat (limited to 'src/tests/common')
| -rw-r--r-- | src/tests/common/bit_field.cpp | 4 | ||||
| -rw-r--r-- | src/tests/common/bit_utils.cpp | 23 | ||||
| -rw-r--r-- | src/tests/common/fibers.cpp | 75 | ||||
| -rw-r--r-- | src/tests/common/multi_level_queue.cpp | 55 | ||||
| -rw-r--r-- | src/tests/common/ring_buffer.cpp | 38 | 
5 files changed, 63 insertions, 132 deletions
| diff --git a/src/tests/common/bit_field.cpp b/src/tests/common/bit_field.cpp index 8ca1889f9..182638000 100644 --- a/src/tests/common/bit_field.cpp +++ b/src/tests/common/bit_field.cpp @@ -68,7 +68,7 @@ TEST_CASE("BitField", "[common]") {                     }});      // bit fields: 01101100111101'10101110'1011'101100 -    REQUIRE(be_bitfield.raw == 0b01101100'11110110'10111010'11101100); +    REQUIRE(be_bitfield.raw == 0b01101100'11110110'10111010'11101100U);      REQUIRE(be_bitfield.a == 0b101100);      REQUIRE(be_bitfield.b == -5); // 1011 as two's complement      REQUIRE(be_bitfield.c == TestEnum::B); @@ -80,7 +80,7 @@ TEST_CASE("BitField", "[common]") {      be_bitfield.d.Assign(0b01010101010101);      std::memcpy(&raw, &be_bitfield, sizeof(raw));      // bit fields: 01010101010101'00001111'1111'000111 -    REQUIRE(be_bitfield.raw == 0b01010101'01010100'00111111'11000111); +    REQUIRE(be_bitfield.raw == 0b01010101'01010100'00111111'11000111U);      REQUIRE(raw == std::array<u8, 4>{{                         0b01010101,                         0b01010100, diff --git a/src/tests/common/bit_utils.cpp b/src/tests/common/bit_utils.cpp deleted file mode 100644 index 479b5995a..000000000 --- a/src/tests/common/bit_utils.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <catch2/catch.hpp> -#include <math.h> -#include "common/bit_util.h" - -namespace Common { - -TEST_CASE("BitUtils::CountTrailingZeroes", "[common]") { -    REQUIRE(Common::CountTrailingZeroes32(0) == 32); -    REQUIRE(Common::CountTrailingZeroes64(0) == 64); -    REQUIRE(Common::CountTrailingZeroes32(9) == 0); -    REQUIRE(Common::CountTrailingZeroes32(8) == 3); -    REQUIRE(Common::CountTrailingZeroes32(0x801000) == 12); -    REQUIRE(Common::CountTrailingZeroes64(9) == 0); -    REQUIRE(Common::CountTrailingZeroes64(8) == 3); -    REQUIRE(Common::CountTrailingZeroes64(0x801000) == 12); -    REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == 36); -} - -} // namespace Common diff --git a/src/tests/common/fibers.cpp b/src/tests/common/fibers.cpp index 4fd92428f..d94492fc6 100644 --- a/src/tests/common/fibers.cpp +++ b/src/tests/common/fibers.cpp @@ -6,18 +6,40 @@  #include <cstdlib>  #include <functional>  #include <memory> +#include <mutex> +#include <stdexcept>  #include <thread>  #include <unordered_map>  #include <vector>  #include <catch2/catch.hpp> -#include <math.h> +  #include "common/common_types.h"  #include "common/fiber.h" -#include "common/spin_lock.h"  namespace Common { +class ThreadIds { +public: +    void Register(u32 id) { +        const auto thread_id = std::this_thread::get_id(); +        std::scoped_lock lock{mutex}; +        if (ids.contains(thread_id)) { +            throw std::logic_error{"Registering the same thread twice"}; +        } +        ids.emplace(thread_id, id); +    } + +    [[nodiscard]] u32 Get() const { +        std::scoped_lock lock{mutex}; +        return ids.at(std::this_thread::get_id()); +    } + +private: +    mutable std::mutex mutex; +    std::unordered_map<std::thread::id, u32> ids; +}; +  class TestControl1 {  public:      TestControl1() = default; @@ -26,7 +48,7 @@ public:      void ExecuteThread(u32 id); -    std::unordered_map<std::thread::id, u32> ids; +    ThreadIds thread_ids;      std::vector<std::shared_ptr<Common::Fiber>> thread_fibers;      std::vector<std::shared_ptr<Common::Fiber>> work_fibers;      std::vector<u32> items; @@ -39,8 +61,7 @@ static void WorkControl1(void* control) {  }  void TestControl1::DoWork() { -    std::thread::id this_id = std::this_thread::get_id(); -    u32 id = ids[this_id]; +    const u32 id = thread_ids.Get();      u32 value = items[id];      for (u32 i = 0; i < id; i++) {          value++; @@ -50,8 +71,7 @@ void TestControl1::DoWork() {  }  void TestControl1::ExecuteThread(u32 id) { -    std::thread::id this_id = std::this_thread::get_id(); -    ids[this_id] = id; +    thread_ids.Register(id);      auto thread_fiber = Fiber::ThreadToFiber();      thread_fibers[id] = thread_fiber;      work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this); @@ -98,8 +118,7 @@ public:              value1 += i;          }          Fiber::YieldTo(fiber1, fiber3); -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          assert1 = id == 1;          value2 += 5000;          Fiber::YieldTo(fiber1, thread_fibers[id]); @@ -115,8 +134,7 @@ public:      }      void DoWork3() { -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          assert2 = id == 0;          value1 += 1000;          Fiber::YieldTo(fiber3, thread_fibers[id]); @@ -125,14 +143,12 @@ public:      void ExecuteThread(u32 id);      void CallFiber1() { -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          Fiber::YieldTo(thread_fibers[id], fiber1);      }      void CallFiber2() { -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          Fiber::YieldTo(thread_fibers[id], fiber2);      } @@ -145,7 +161,7 @@ public:      u32 value2{};      std::atomic<bool> trap{true};      std::atomic<bool> trap2{true}; -    std::unordered_map<std::thread::id, u32> ids; +    ThreadIds thread_ids;      std::vector<std::shared_ptr<Common::Fiber>> thread_fibers;      std::shared_ptr<Common::Fiber> fiber1;      std::shared_ptr<Common::Fiber> fiber2; @@ -168,15 +184,13 @@ static void WorkControl2_3(void* control) {  }  void TestControl2::ExecuteThread(u32 id) { -    std::thread::id this_id = std::this_thread::get_id(); -    ids[this_id] = id; +    thread_ids.Register(id);      auto thread_fiber = Fiber::ThreadToFiber();      thread_fibers[id] = thread_fiber;  }  void TestControl2::Exit() { -    std::thread::id this_id = std::this_thread::get_id(); -    u32 id = ids[this_id]; +    const u32 id = thread_ids.Get();      thread_fibers[id]->Exit();  } @@ -193,7 +207,7 @@ static void ThreadStart2_2(u32 id, TestControl2& test_control) {  }  /** This test checks for fiber thread exchange configuration and validates that fibers are - *  that a fiber has been succesfully transfered from one thread to another and that the TLS + *  that a fiber has been successfully transferred from one thread to another and that the TLS   *  region of the thread is kept while changing fibers.   */  TEST_CASE("Fibers::InterExchange", "[common]") { @@ -228,24 +242,21 @@ public:      void DoWork1() {          value1 += 1;          Fiber::YieldTo(fiber1, fiber2); -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          value3 += 1;          Fiber::YieldTo(fiber1, thread_fibers[id]);      }      void DoWork2() {          value2 += 1; -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          Fiber::YieldTo(fiber2, thread_fibers[id]);      }      void ExecuteThread(u32 id);      void CallFiber1() { -        std::thread::id this_id = std::this_thread::get_id(); -        u32 id = ids[this_id]; +        const u32 id = thread_ids.Get();          Fiber::YieldTo(thread_fibers[id], fiber1);      } @@ -254,7 +265,7 @@ public:      u32 value1{};      u32 value2{};      u32 value3{}; -    std::unordered_map<std::thread::id, u32> ids; +    ThreadIds thread_ids;      std::vector<std::shared_ptr<Common::Fiber>> thread_fibers;      std::shared_ptr<Common::Fiber> fiber1;      std::shared_ptr<Common::Fiber> fiber2; @@ -271,15 +282,13 @@ static void WorkControl3_2(void* control) {  }  void TestControl3::ExecuteThread(u32 id) { -    std::thread::id this_id = std::this_thread::get_id(); -    ids[this_id] = id; +    thread_ids.Register(id);      auto thread_fiber = Fiber::ThreadToFiber();      thread_fibers[id] = thread_fiber;  }  void TestControl3::Exit() { -    std::thread::id this_id = std::this_thread::get_id(); -    u32 id = ids[this_id]; +    const u32 id = thread_ids.Get();      thread_fibers[id]->Exit();  } @@ -290,7 +299,7 @@ static void ThreadStart3(u32 id, TestControl3& test_control) {  }  /** This test checks for one two threads racing for starting the same fiber. - *  It checks execution occured in an ordered manner and by no time there were + *  It checks execution occurred in an ordered manner and by no time there were   *  two contexts at the same time.   */  TEST_CASE("Fibers::StartRace", "[common]") { diff --git a/src/tests/common/multi_level_queue.cpp b/src/tests/common/multi_level_queue.cpp deleted file mode 100644 index cca7ec7da..000000000 --- a/src/tests/common/multi_level_queue.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2019 Yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <catch2/catch.hpp> -#include <math.h> -#include "common/common_types.h" -#include "common/multi_level_queue.h" - -namespace Common { - -TEST_CASE("MultiLevelQueue", "[common]") { -    std::array<f32, 8> values = {0.0, 5.0, 1.0, 9.0, 8.0, 2.0, 6.0, 7.0}; -    Common::MultiLevelQueue<f32, 64> mlq; -    REQUIRE(mlq.empty()); -    mlq.add(values[2], 2); -    mlq.add(values[7], 7); -    mlq.add(values[3], 3); -    mlq.add(values[4], 4); -    mlq.add(values[0], 0); -    mlq.add(values[5], 5); -    mlq.add(values[6], 6); -    mlq.add(values[1], 1); -    u32 index = 0; -    bool all_set = true; -    for (auto& f : mlq) { -        all_set &= (f == values[index]); -        index++; -    } -    REQUIRE(all_set); -    REQUIRE(!mlq.empty()); -    f32 v = 8.0; -    mlq.add(v, 2); -    v = -7.0; -    mlq.add(v, 2, false); -    REQUIRE(mlq.front(2) == -7.0); -    mlq.yield(2); -    REQUIRE(mlq.front(2) == values[2]); -    REQUIRE(mlq.back(2) == -7.0); -    REQUIRE(mlq.empty(8)); -    v = 10.0; -    mlq.add(v, 8); -    mlq.adjust(v, 8, 9); -    REQUIRE(mlq.front(9) == v); -    REQUIRE(mlq.empty(8)); -    REQUIRE(!mlq.empty(9)); -    mlq.adjust(values[0], 0, 9); -    REQUIRE(mlq.highest_priority_set() == 1); -    REQUIRE(mlq.lowest_priority_set() == 9); -    mlq.remove(values[1], 1); -    REQUIRE(mlq.highest_priority_set() == 2); -    REQUIRE(mlq.empty(1)); -} - -} // namespace Common diff --git a/src/tests/common/ring_buffer.cpp b/src/tests/common/ring_buffer.cpp index c883c4d56..903626e4b 100644 --- a/src/tests/common/ring_buffer.cpp +++ b/src/tests/common/ring_buffer.cpp @@ -14,70 +14,70 @@  namespace Common {  TEST_CASE("RingBuffer: Basic Tests", "[common]") { -    RingBuffer<char, 4, 1> buf; +    RingBuffer<char, 4> buf;      // Pushing values into a ring buffer with space should succeed.      for (std::size_t i = 0; i < 4; i++) {          const char elem = static_cast<char>(i);          const std::size_t count = buf.Push(&elem, 1); -        REQUIRE(count == 1); +        REQUIRE(count == 1U);      } -    REQUIRE(buf.Size() == 4); +    REQUIRE(buf.Size() == 4U);      // Pushing values into a full ring buffer should fail.      {          const char elem = static_cast<char>(42);          const std::size_t count = buf.Push(&elem, 1); -        REQUIRE(count == 0); +        REQUIRE(count == 0U);      } -    REQUIRE(buf.Size() == 4); +    REQUIRE(buf.Size() == 4U);      // Popping multiple values from a ring buffer with values should succeed.      {          const std::vector<char> popped = buf.Pop(2); -        REQUIRE(popped.size() == 2); +        REQUIRE(popped.size() == 2U);          REQUIRE(popped[0] == 0);          REQUIRE(popped[1] == 1);      } -    REQUIRE(buf.Size() == 2); +    REQUIRE(buf.Size() == 2U);      // Popping a single value from a ring buffer with values should succeed.      {          const std::vector<char> popped = buf.Pop(1); -        REQUIRE(popped.size() == 1); +        REQUIRE(popped.size() == 1U);          REQUIRE(popped[0] == 2);      } -    REQUIRE(buf.Size() == 1); +    REQUIRE(buf.Size() == 1U);      // Pushing more values than space available should partially suceed.      {          std::vector<char> to_push(6);          std::iota(to_push.begin(), to_push.end(), 88);          const std::size_t count = buf.Push(to_push); -        REQUIRE(count == 3); +        REQUIRE(count == 3U);      } -    REQUIRE(buf.Size() == 4); +    REQUIRE(buf.Size() == 4U);      // Doing an unlimited pop should pop all values.      {          const std::vector<char> popped = buf.Pop(); -        REQUIRE(popped.size() == 4); +        REQUIRE(popped.size() == 4U);          REQUIRE(popped[0] == 3);          REQUIRE(popped[1] == 88);          REQUIRE(popped[2] == 89);          REQUIRE(popped[3] == 90);      } -    REQUIRE(buf.Size() == 0); +    REQUIRE(buf.Size() == 0U);  }  TEST_CASE("RingBuffer: Threaded Test", "[common]") { -    RingBuffer<char, 4, 2> buf; +    RingBuffer<char, 8> buf;      const char seed = 42;      const std::size_t count = 1000000;      std::size_t full = 0; @@ -92,8 +92,8 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") {          std::array<char, 2> value = {seed, seed};          std::size_t i = 0;          while (i < count) { -            if (const std::size_t c = buf.Push(&value[0], 1); c > 0) { -                REQUIRE(c == 1); +            if (const std::size_t c = buf.Push(&value[0], 2); c > 0) { +                REQUIRE(c == 2U);                  i++;                  next_value(value);              } else { @@ -107,8 +107,8 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") {          std::array<char, 2> value = {seed, seed};          std::size_t i = 0;          while (i < count) { -            if (const std::vector<char> v = buf.Pop(1); v.size() > 0) { -                REQUIRE(v.size() == 2); +            if (const std::vector<char> v = buf.Pop(2); v.size() > 0) { +                REQUIRE(v.size() == 2U);                  REQUIRE(v[0] == value[0]);                  REQUIRE(v[1] == value[1]);                  i++; @@ -123,7 +123,7 @@ TEST_CASE("RingBuffer: Threaded Test", "[common]") {      producer.join();      consumer.join(); -    REQUIRE(buf.Size() == 0); +    REQUIRE(buf.Size() == 0U);      printf("RingBuffer: Threaded Test: full: %zu, empty: %zu\n", full, empty);  } | 
