Created
April 21, 2024 13:12
-
-
Save ot/64712433d33dab75559731f84dba5304 to your computer and use it in GitHub Desktop.
stdexec::static_thread_pool repro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.14 FATAL_ERROR) | |
project(deadlock_repro) | |
include(CPM.cmake) | |
CPMAddPackage( | |
NAME stdexec | |
GITHUB_REPOSITORY NVIDIA/stdexec | |
GIT_TAG main | |
) | |
CPMAddPackage( | |
NAME libunifex | |
GITHUB_REPOSITORY facebookexperimental/libunifex | |
GIT_TAG main | |
) | |
add_executable(deadlock deadlock.cpp) | |
target_link_libraries(deadlock STDEXEC::stdexec) | |
add_executable(deadlock_unifex deadlock.cpp) | |
target_compile_definitions(deadlock_unifex PRIVATE UNIFEX) | |
target_link_libraries(deadlock_unifex unifex) | |
add_executable(no_parallelism no_parallelism.cpp) | |
target_link_libraries(no_parallelism STDEXEC::stdexec) | |
add_executable(no_parallelism_unifex no_parallelism.cpp) | |
target_compile_definitions(no_parallelism_unifex PRIVATE UNIFEX) | |
target_link_libraries(no_parallelism_unifex unifex) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SPDX-License-Identifier: MIT | |
# | |
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors | |
set(CPM_DOWNLOAD_VERSION 0.39.0) | |
set(CPM_HASH_SUM "66639bcac9dd2907b2918de466783554c1334446b9874e90d38e3778d404c2ef") | |
if(CPM_SOURCE_CACHE) | |
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") | |
elseif(DEFINED ENV{CPM_SOURCE_CACHE}) | |
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") | |
else() | |
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") | |
endif() | |
# Expand relative path. This is important if the provided path contains a tilde (~) | |
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) | |
file(DOWNLOAD | |
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake | |
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} | |
) | |
include(${CPM_DOWNLOAD_LOCATION}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef UNIFEX | |
#include <unifex/just.hpp> | |
#include <unifex/on.hpp> | |
#include <unifex/static_thread_pool.hpp> | |
#include <unifex/sync_wait.hpp> | |
#include <unifex/then.hpp> | |
using namespace unifex; | |
#else | |
#include <exec/static_thread_pool.hpp> | |
#include <stdexec/execution.hpp> | |
using namespace stdexec; | |
using namespace exec; | |
#endif | |
int main() { | |
// XXX: 2 should be sufficient, but libunifex sometimes deadlocks. 3 | |
// always works. Should be investigated separately. | |
static_thread_pool pool(3); | |
auto sched = pool.get_scheduler(); | |
auto parent = [&] { | |
// parent is occupying one thread, but the pool should have more | |
// available for this to complete. | |
sync_wait(on(sched, just())); | |
}; | |
sync_wait(on(sched, just() | then(parent))); | |
std::printf("Done\n"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <thread> | |
#include <vector> | |
#ifdef UNIFEX | |
#include <unifex/any_sender_of.hpp> | |
#include <unifex/async_scope.hpp> | |
#include <unifex/just.hpp> | |
#include <unifex/on.hpp> | |
#include <unifex/static_thread_pool.hpp> | |
#include <unifex/sync_wait.hpp> | |
#include <unifex/then.hpp> | |
using namespace unifex; | |
#define ON_EMPTY complete | |
#define SPAWN detached_spawn | |
#else | |
#include <exec/any_sender_of.hpp> | |
#include <exec/async_scope.hpp> | |
#include <exec/static_thread_pool.hpp> | |
#include <stdexec/execution.hpp> | |
using namespace stdexec; | |
using namespace exec; | |
#define ON_EMPTY on_empty | |
#define SPAWN spawn | |
#endif | |
int main() { | |
const size_t num_threads = 8; | |
static_thread_pool pool(num_threads); | |
auto sched = pool.get_scheduler(); | |
async_scope scope; | |
auto parent = [&] { | |
std::printf("Parent\n"); | |
auto child = [] { | |
std::printf("Child\n"); | |
// Simulate a long-running (possibly CPU-intensive) task with a | |
// sleep. | |
std::this_thread::sleep_for(std::chrono::seconds(1)); | |
}; | |
for (size_t i = 0; i < num_threads; ++i) { | |
scope.SPAWN(on(sched, just() | then(child))); | |
} | |
}; | |
sync_wait(on(sched, just() | then(parent))); | |
sync_wait(scope.ON_EMPTY()); | |
std::printf("Done\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment