Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Deadlock when using nested tasks + semaphore #506

@olologin

Description

@olologin

Describe the bug
With some low probability the following unittest deadlocks instead of completing.
It seems tf somehow "forgets" to execute the most nested task which is supposed to do the actual initialization of lazy value, and the rest of threads are either waiting for a task, or just get stuck.

To Reproduce
Just paste the following snippet into any uniitest file, build and run it, normally the issue shows up on iteration# 200-400.

TEST_CASE("LazyInit_Deadlocks.16threads")
{
	using namespace std::chrono_literals;

	for (size_t i = 0; i < 10000; ++i)
	{
		//std::cout << i << std::endl;
		tf::Executor executor(16);
		tf::Semaphore semaphore(1);
		std::atomic_bool has_value = false;
		
		// The following lambda simulates lazy initializer of some complex and slow to initialize variable
		auto lazy_data = [&]()
		{
			// If we already have a value, return it
			if (!has_value.load(std::memory_order_acquire))
			{
				// Otherwise, calculate it in a task
				tf::Taskflow taskflow2;
				// Let's imagine the following task is just some slow and complex initialization of some meaningful variable
				auto task = taskflow2.emplace([&]() {
					if (!has_value.load(std::memory_order_acquire))
					{
						tf::Taskflow taskflow3;
						taskflow3.emplace([&] { std::this_thread::sleep_for(1ms); });
						executor.corun(taskflow3);
						has_value.store(true, std::memory_order_release);
					}
					});
				task.acquire(semaphore);
				task.release(semaphore);
				executor.corun(taskflow2);
			}
			return 99;
		};

		tf::Taskflow taskflow1;
		for (size_t k = 0; k < 16; ++k)
		{
			taskflow1.emplace(
				[&]
				{
					lazy_data();
				});
		}

		// If the following line fails - you are expiriencing deadlock
		REQUIRE(executor.run(taskflow1).wait_for(5s) == std::future_status::ready);
	}
}

Desktop (please complete the following information):
taskflow 3.6, Windows 10, VS2019, x64 build and Ryzen 3800x CPU.

Additional context
No other information available.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions