Commit 8bce0676 by Antonio Maiorano

Subzero: replace Win32 fibers with Marl for couroutines

* This change was authored by bclayton@, with some modifications. * Replaces Win32 fiber implementation with marl tasks, making coroutines work on all marl-supported platforms. Bug: b/145754674 Change-Id: Ic3de82afc69549e1d56688c6faf8077a6f446ee0 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41788 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent b8bae186
......@@ -1549,6 +1549,25 @@ if(LINUX)
target_link_libraries(llvm dl)
endif()
###########################################################
# marl
###########################################################
if(BUILD_MARL)
set(MARL_THIRD_PARTY_DIR ${THIRD_PARTY_DIR})
add_subdirectory(third_party/marl)
endif()
###########################################################
# cppdap
###########################################################
if(SWIFTSHADER_BUILD_CPPDAP)
set(CPPDAP_THIRD_PARTY_DIR ${THIRD_PARTY_DIR})
add_subdirectory(${CPPDAP_DIR})
endif()
###########################################################
# Subzero
###########################################################
......@@ -1696,6 +1715,8 @@ if(${REACTOR_BACKEND} STREQUAL "Subzero")
)
target_link_libraries(ReactorSubzero SubzeroDependencies)
target_link_libraries(ReactorSubzero marl)
if(WIN32)
target_compile_definitions(ReactorSubzero PRIVATE SUBZERO_USE_MICROSOFT_ABI)
endif()
......@@ -2157,16 +2178,6 @@ if(SWIFTSHADER_BUILD_GLES_CM)
)
endif(SWIFTSHADER_BUILD_GLES_CM)
if(BUILD_MARL)
set(MARL_THIRD_PARTY_DIR ${THIRD_PARTY_DIR})
add_subdirectory(third_party/marl)
endif()
if(SWIFTSHADER_BUILD_CPPDAP)
set(CPPDAP_THIRD_PARTY_DIR ${THIRD_PARTY_DIR})
add_subdirectory(${CPPDAP_DIR})
endif()
if(SWIFTSHADER_BUILD_VULKAN)
add_library(vk_swiftshader SHARED ${VULKAN_LIST})
......@@ -2322,9 +2333,9 @@ if(SWIFTSHADER_BUILD_TESTS)
)
if(NOT WIN32 AND ${REACTOR_BACKEND} STREQUAL "Subzero")
target_link_libraries(ReactorUnitTests ${Reactor} pthread dl)
target_link_libraries(ReactorUnitTests ${Reactor} marl pthread dl)
else()
target_link_libraries(ReactorUnitTests ${Reactor})
target_link_libraries(ReactorUnitTests ${Reactor} marl)
endif()
set(GLES_UNITTESTS_LIST
......@@ -2390,7 +2401,7 @@ if(SWIFTSHADER_BUILD_BENCHMARKS)
)
add_executable(ReactorBenchmarks ${REACTOR_BENCHMARK_LIST})
target_link_libraries(ReactorBenchmarks benchmark::benchmark ${Reactor})
target_link_libraries(ReactorBenchmarks benchmark::benchmark marl ${Reactor})
set_target_properties(ReactorBenchmarks PROPERTIES
COMPILE_OPTIONS "${SWIFTSHADER_COMPILE_OPTIONS};${WARNINGS_AS_ERRORS}"
......
......@@ -18,6 +18,9 @@
#include "gtest/gtest.h"
#include "marl/defer.h"
#include "marl/scheduler.h"
#include <array>
#include <cmath>
#include <thread>
......@@ -155,6 +158,38 @@ std::vector<std::string> split(const std::string &s)
return result;
}
static const std::vector<int> fibonacci = {
0,
1,
1,
2,
3,
5,
8,
13,
21,
34,
55,
89,
144,
233,
377,
610,
987,
1597,
2584,
4181,
6765,
10946,
17711,
28657,
46368,
75025,
121393,
196418,
317811,
};
TEST(ReactorUnitTests, PrintPrimitiveTypes)
{
#if defined(ENABLE_RR_PRINT) && !defined(ENABLE_RR_EMIT_PRINT_LOCATION)
......@@ -2070,6 +2105,30 @@ TYPED_TEST(GEPTest, PtrOffsets)
}
}
TEST(ReactorUnitTests, Fibonacci)
{
FunctionT<int(int)> function;
{
Int n = function.Arg<0>();
Int current = 0;
Int next = 1;
For(Int i = 0, i < n, i++)
{
auto tmp = current + next;
current = next;
next = tmp;
}
Return(current);
}
auto routine = function("one");
for(size_t i = 0; i < fibonacci.size(); i++)
{
EXPECT_EQ(routine(i), fibonacci[i]);
}
}
TEST(ReactorUnitTests, Coroutines_Fibonacci)
{
if(!rr::Caps.CoroutinesSupported)
......@@ -2078,6 +2137,11 @@ TEST(ReactorUnitTests, Coroutines_Fibonacci)
return;
}
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
Coroutine<int()> function;
{
Yield(Int(0));
......@@ -2095,45 +2159,11 @@ TEST(ReactorUnitTests, Coroutines_Fibonacci)
auto coroutine = function();
int32_t expected[] = {
0,
1,
1,
2,
3,
5,
8,
13,
21,
34,
55,
89,
144,
233,
377,
610,
987,
1597,
2584,
4181,
6765,
10946,
17711,
28657,
46368,
75025,
121393,
196418,
317811,
};
auto count = sizeof(expected) / sizeof(expected[0]);
for(size_t i = 0; i < count; i++)
for(size_t i = 0; i < fibonacci.size(); i++)
{
int out = 0;
EXPECT_EQ(coroutine->await(out), true);
EXPECT_EQ(out, expected[i]);
EXPECT_EQ(out, fibonacci[i]);
}
}
......@@ -2145,6 +2175,11 @@ TEST(ReactorUnitTests, Coroutines_Parameters)
return;
}
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
Coroutine<uint8_t(uint8_t * data, int count)> function;
{
Pointer<Byte> data = function.Arg<0>();
......@@ -2186,6 +2221,11 @@ TEST(ReactorUnitTests, Coroutines_Vectors)
return;
}
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
Coroutine<int()> function;
{
Int4 a{ 1, 2, 3, 4 };
......@@ -2220,6 +2260,11 @@ TEST(ReactorUnitTests, Coroutines_NoYield)
return;
}
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
for(int i = 0; i < 2; ++i)
{
Coroutine<int()> function;
......@@ -2244,6 +2289,11 @@ TEST(ReactorUnitTests, Coroutines_Parallel)
return;
}
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
//scheduler.bind();
//defer(scheduler.unbind());
Coroutine<int()> function;
{
Yield(Int(0));
......@@ -2262,53 +2312,22 @@ TEST(ReactorUnitTests, Coroutines_Parallel)
// Must call on same thread that creates the coroutine
function.finalize();
constexpr int32_t expected[] = {
0,
1,
1,
2,
3,
5,
8,
13,
21,
34,
55,
89,
144,
233,
377,
610,
987,
1597,
2584,
4181,
6765,
10946,
17711,
28657,
46368,
75025,
121393,
196418,
317811,
};
constexpr auto count = sizeof(expected) / sizeof(expected[0]);
std::vector<std::thread> threads;
const size_t numThreads = 100;
for(size_t t = 0; t < numThreads; ++t)
{
threads.emplace_back([&] {
scheduler.bind();
defer(scheduler.unbind());
auto coroutine = function();
for(size_t i = 0; i < count; i++)
for(size_t i = 0; i < fibonacci.size(); i++)
{
int out = 0;
EXPECT_EQ(coroutine->await(out), true);
EXPECT_EQ(out, expected[i]);
EXPECT_EQ(out, fibonacci[i]);
}
});
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment