scheduling_tests.cpp 2.01 KB
Newer Older
1
#include <catch.hpp>
2
#include <atomic>
3

4
#include "pls/pls.h"
5 6

using namespace pls::internal::scheduling;
7
using namespace pls::internal::scheduling::lock_free;
8

9 10 11
constexpr int MAX_NUM_TASKS = 32;
constexpr int MAX_STACK_SIZE = 1024 * 8;

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
TEST_CASE("scheduler correctly initializes", "[internal/scheduling/scheduler]") {
  const unsigned num_tasks = 16;
  const unsigned num_threads = 4;

  pls::scheduler scheduler{num_threads, num_tasks, 4096, false};

  SECTION("task chains are valid") {
    for (unsigned i = 0; i < num_threads; i++) {
      task_manager &manager = scheduler.task_manager_for(i);
      for (unsigned j = 0; j < num_tasks; j++) {
        REQUIRE(manager.get_task(j)->depth_ == j);
        REQUIRE(manager.get_task(j)->thread_id_ == i);

        if (j < num_tasks - 1) {
          REQUIRE(manager.get_task(j)->next_ == manager.get_task(j + 1));
        }
        if (j > 0) {
          REQUIRE(manager.get_task(j)->prev_ == manager.get_task(j - 1));
        }
      }
    }
  }
}

36
TEST_CASE("tasks distributed over workers (do not block)", "[internal/scheduling/scheduler.h]") {
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  scheduler scheduler{3, MAX_NUM_TASKS, MAX_STACK_SIZE};

  std::atomic<int> num_run{0};
  scheduler.perform_work([&] {
    scheduler::spawn([&] {
      num_run++;
      while (num_run < 3);
    });
    scheduler::spawn([&] {
      while (num_run < 1);
      num_run++;
      while (num_run < 3);
    });
    scheduler::spawn([&] {
      while (num_run < 2);
      num_run++;
    });
    scheduler::sync();
  });
56
  REQUIRE(num_run == 3);
57
}
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

unsigned fib_serial(unsigned n) {
  if (n <= 1) {
    return n;
  }

  return fib_serial(n - 1) + fib_serial(n - 2);
}

unsigned fib_pls(unsigned n) {
  if (n <= 1) {
    return n;
  }

  unsigned a, b;
  pls::invoke(
      [&a, n] { a = fib_pls(n - 1); },
      [&b, n] { b = fib_pls(n - 2); }
  );
  return a + b;
}

TEST_CASE("simple fib", "[internal/scheduling/scheduler]") {
  scheduler scheduler{3, MAX_NUM_TASKS, MAX_STACK_SIZE};

  scheduler.perform_work([&] {
    REQUIRE(fib_serial(28) == fib_pls(28));
  });
}