Skip to content

Commit

Permalink
Add support for running function at thread termination (#46)
Browse files Browse the repository at this point in the history
* Add support for running function at thread termination

* Simplify logic

* Make work with multiple runs of systest

---------

Co-authored-by: Matthew Parkinson <[email protected]>
  • Loading branch information
vishalgupta97 and mjp41 authored Sep 4, 2024
1 parent 32bfada commit 21345e8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/rt/debug/harness.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class SystematicTestHarness
size_t seed_upper;
high_resolution_clock::time_point start;

void (*run_at_termination)(void) = nullptr;

SystematicTestHarness(int argc, const char* const* argv) : opt(argc, argv)
{
std::cout << "Harness starting." << std::endl;
Expand Down Expand Up @@ -155,7 +157,8 @@ class SystematicTestHarness
#else
UNUSED(seed);
#endif
sched.init(cores);

sched.init(cores, run_at_termination);

f(std::forward<Args>(args)...);

Expand Down
4 changes: 4 additions & 0 deletions src/rt/sched/schedulerthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ namespace verona::rt
SchedulerThread* prev = nullptr;
SchedulerThread* next = nullptr;

void (*run_at_termination)(void) = nullptr;

SchedulerThread()
{
Logging::cout() << "Scheduler Thread created" << Logging::endl;
Expand Down Expand Up @@ -223,6 +225,8 @@ namespace verona::rt
}

Systematic::finished_thread();
if (run_at_termination)
run_at_termination();

// Reset the local thread pointer as this physical thread could be reused
// for a different SchedulerThread later.
Expand Down
3 changes: 2 additions & 1 deletion src/rt/sched/threadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ namespace verona::rt
T::schedule_lifo(core, w);
}

void init(size_t count)
void init(size_t count, void (*run_at_termination)(void) = nullptr)
{
Logging::cout() << "Init runtime" << Logging::endl;

Expand All @@ -219,6 +219,7 @@ namespace verona::rt
{
T* t = new T;
t->systematic_id = count;
t->run_at_termination = run_at_termination;
#ifdef USE_SYSTEMATIC_TESTING
t->local_systematic =
Systematic::create_systematic_thread(t->systematic_id);
Expand Down
74 changes: 74 additions & 0 deletions test/func/run-at-termination/run-at-termination.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright Microsoft and Project Verona Contributors.
// SPDX-License-Identifier: MIT

#include <cpp/when.h>
#include <debug/harness.h>

/**
* Check if thread_local variables are correctly added to global variable
* once the thread finishes.
*
* Create NUM_OPS behaviour where each behaviour increments the thread_local ops
* variable by NUM_OPS At thread termination, add the ops variable to the
* total_ops variable. Finally, check if the total_ops variable == NUM_OPS *
* NUM_OPS
*/

static constexpr uint64_t NUM_OPS = 10;

// How many scheduler cores are being used.
size_t cores{0};

// Thread local variable to store the number of operations.
thread_local long ops{0};

using namespace verona::cpp;

void test_body()
{
// Run NUM_OPS behaviours, each incrementing ops by NUM_OPS.
for (int i = 0; i < NUM_OPS; i++)
{
when() << []() {
for (int i = 0; i < NUM_OPS; i++)
ops++;
};
}
}

void finish(void)
{
static std::atomic<size_t> finished_count{0};
static std::atomic<size_t> total_ops{0};

// Add the thread local ops to the total_ops.
total_ops.fetch_add(ops);
// Reset thread local for subsequent runs.
ops = 0;

// Increment the finished count.
auto prev = finished_count.fetch_add(1);

// Check if was the last core to finish.
if (prev != cores - 1)
return;

// Actual check.
check(total_ops.load() == (NUM_OPS * NUM_OPS));

// Reset the counters for the next run.
finished_count = 0;
total_ops = 0;
}

int main(int argc, char** argv)
{
SystematicTestHarness harness(argc, argv);

cores = harness.cores;

harness.run_at_termination = finish;
harness.run(test_body);

return 0;
}

0 comments on commit 21345e8

Please sign in to comment.