// Copyright Microsoft and Project Verona Contributors. // SPDX-License-Identifier: MIT #include "args.h" #include #include #include using namespace verona::cpp; struct Fork { size_t uses{0}; void use() { ++uses; } ~Fork() { check((HUNGER * 2) == uses); } }; cown_ptr get_left(std::vector>& forks, size_t index) { return forks[index]; } cown_ptr get_right(std::vector>& forks, size_t index) { return forks[(index + 1) % NUM_PHILOSOPHERS]; } struct Philosopher { cown_ptr left; cown_ptr right; size_t hunger; Philosopher(std::vector>& forks, size_t index) : left(get_left(forks, index)), right(get_right(forks, index)), hunger(HUNGER) {} static void eat(std::unique_ptr phil) { if (phil->hunger > 0) { when(phil->left, phil->right) << [phil = std::move(phil)]( acquired_cown f1, acquired_cown f2) mutable { f1->use(); f2->use(); busy_loop(WORK_USEC); phil->hunger--; eat(std::move(phil)); }; } } }; void test_body() { std::vector> forks; for (size_t i = 0; i < NUM_PHILOSOPHERS; i++) { forks.push_back(make_cown()); } if (OPTIMAL_ORDER) { for (size_t i = 0; i < NUM_PHILOSOPHERS; i += 2) { auto phil = std::make_unique(forks, i); Philosopher::eat(std::move(phil)); } for (size_t i = 1; i < NUM_PHILOSOPHERS; i += 2) { auto phil = std::make_unique(forks, i); Philosopher::eat(std::move(phil)); } } else { for (size_t i = 0; i < NUM_PHILOSOPHERS; i++) { auto phil = std::make_unique(forks, i); Philosopher::eat(std::move(phil)); } } } void test1() { when() << []() { test_body(); }; } int verona_main(SystematicTestHarness& harness) { harness.run(test1); return 0; }