Commit 8f2d48f9 by Antonio Maiorano

Subzero: hide dependency on Marl

Subzero maintains an internal scheduler that it uses only if there's no external scheduler already bound on the current thread. This removes the dependency on Marl in ReactorUnitTests, as we can rely on the internal one being used. Bug: b/145754674 Change-Id: Iddbaa299ccd904a87b8aa86e82e5517c9d72ef59 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41789Tested-by: 's avatarAntonio Maiorano <amaiorano@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com>
parent be4a731f
...@@ -2329,9 +2329,9 @@ if(SWIFTSHADER_BUILD_TESTS) ...@@ -2329,9 +2329,9 @@ if(SWIFTSHADER_BUILD_TESTS)
) )
if(NOT WIN32 AND ${REACTOR_BACKEND} STREQUAL "Subzero") if(NOT WIN32 AND ${REACTOR_BACKEND} STREQUAL "Subzero")
target_link_libraries(ReactorUnitTests ${Reactor} marl pthread dl) target_link_libraries(ReactorUnitTests ${Reactor} pthread dl)
else() else()
target_link_libraries(ReactorUnitTests ${Reactor} marl) target_link_libraries(ReactorUnitTests ${Reactor})
endif() endif()
set(GLES_UNITTESTS_LIST set(GLES_UNITTESTS_LIST
......
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "marl/defer.h"
#include "marl/scheduler.h"
#include <array> #include <array>
#include <cmath> #include <cmath>
#include <thread> #include <thread>
...@@ -2137,11 +2134,6 @@ TEST(ReactorUnitTests, Coroutines_Fibonacci) ...@@ -2137,11 +2134,6 @@ TEST(ReactorUnitTests, Coroutines_Fibonacci)
return; return;
} }
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
Coroutine<int()> function; Coroutine<int()> function;
{ {
Yield(Int(0)); Yield(Int(0));
...@@ -2175,11 +2167,6 @@ TEST(ReactorUnitTests, Coroutines_Parameters) ...@@ -2175,11 +2167,6 @@ TEST(ReactorUnitTests, Coroutines_Parameters)
return; return;
} }
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
Coroutine<uint8_t(uint8_t * data, int count)> function; Coroutine<uint8_t(uint8_t * data, int count)> function;
{ {
Pointer<Byte> data = function.Arg<0>(); Pointer<Byte> data = function.Arg<0>();
...@@ -2221,11 +2208,6 @@ TEST(ReactorUnitTests, Coroutines_Vectors) ...@@ -2221,11 +2208,6 @@ TEST(ReactorUnitTests, Coroutines_Vectors)
return; return;
} }
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
Coroutine<int()> function; Coroutine<int()> function;
{ {
Int4 a{ 1, 2, 3, 4 }; Int4 a{ 1, 2, 3, 4 };
...@@ -2260,11 +2242,6 @@ TEST(ReactorUnitTests, Coroutines_NoYield) ...@@ -2260,11 +2242,6 @@ TEST(ReactorUnitTests, Coroutines_NoYield)
return; return;
} }
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
scheduler.bind();
defer(scheduler.unbind());
for(int i = 0; i < 2; ++i) for(int i = 0; i < 2; ++i)
{ {
Coroutine<int()> function; Coroutine<int()> function;
...@@ -2289,11 +2266,6 @@ TEST(ReactorUnitTests, Coroutines_Parallel) ...@@ -2289,11 +2266,6 @@ TEST(ReactorUnitTests, Coroutines_Parallel)
return; return;
} }
marl::Scheduler scheduler;
scheduler.setWorkerThreadCount(8);
//scheduler.bind();
//defer(scheduler.unbind());
Coroutine<int()> function; Coroutine<int()> function;
{ {
Yield(Int(0)); Yield(Int(0));
...@@ -2318,9 +2290,6 @@ TEST(ReactorUnitTests, Coroutines_Parallel) ...@@ -2318,9 +2290,6 @@ TEST(ReactorUnitTests, Coroutines_Parallel)
for(size_t t = 0; t < numThreads; ++t) for(size_t t = 0; t < numThreads; ++t)
{ {
threads.emplace_back([&] { threads.emplace_back([&] {
scheduler.bind();
defer(scheduler.unbind());
auto coroutine = function(); auto coroutine = function();
for(size_t i = 0; i < fibonacci.size(); i++) for(size_t i = 0; i < fibonacci.size(); i++)
......
...@@ -268,7 +268,16 @@ Ice::Fdstream *out = nullptr; ...@@ -268,7 +268,16 @@ Ice::Fdstream *out = nullptr;
// Coroutine globals // Coroutine globals
rr::Type *coroYieldType = nullptr; rr::Type *coroYieldType = nullptr;
std::shared_ptr<rr::CoroutineGenerator> coroGen; std::shared_ptr<rr::CoroutineGenerator> coroGen;
marl::Scheduler &getOrCreateScheduler()
{
static auto scheduler = [] {
auto s = std::make_unique<marl::Scheduler>();
s->setWorkerThreadCount(8);
return s;
}();
return *scheduler;
}
} // Anonymous namespace } // Anonymous namespace
namespace { namespace {
...@@ -4467,6 +4476,7 @@ namespace coro { ...@@ -4467,6 +4476,7 @@ namespace coro {
// Lifetime: from yield to when CoroutineEntryDestroy generated function is called. // Lifetime: from yield to when CoroutineEntryDestroy generated function is called.
struct CoroutineData struct CoroutineData
{ {
bool useInternalScheduler = false;
marl::Event suspended; // the coroutine is suspended on a yield() marl::Event suspended; // the coroutine is suspended on a yield()
marl::Event resumed; // the caller is suspended on an await() marl::Event resumed; // the caller is suspended on an await()
marl::Event done{ marl::Event::Mode::Manual }; // the coroutine should stop at the next yield() marl::Event done{ marl::Event::Mode::Manual }; // the coroutine should stop at the next yield()
...@@ -4513,6 +4523,10 @@ void stop(Nucleus::CoroutineHandle handle) ...@@ -4513,6 +4523,10 @@ void stop(Nucleus::CoroutineHandle handle)
coroData->done.signal(); // signal that the coroutine should stop at next (or current) yield. coroData->done.signal(); // signal that the coroutine should stop at next (or current) yield.
coroData->resumed.signal(); // wake the coroutine if blocked on a yield. coroData->resumed.signal(); // wake the coroutine if blocked on a yield.
coroData->terminated.wait(); // wait for the coroutine to return. coroData->terminated.wait(); // wait for the coroutine to return.
if(coroData->useInternalScheduler)
{
::getOrCreateScheduler().unbind();
}
coro::destroyCoroutineData(coroData); // free the coroutine data. coro::destroyCoroutineData(coroData); // free the coroutine data.
} }
...@@ -4752,6 +4766,12 @@ static Nucleus::CoroutineHandle invokeCoroutineBegin(std::function<Nucleus::Coro ...@@ -4752,6 +4766,12 @@ static Nucleus::CoroutineHandle invokeCoroutineBegin(std::function<Nucleus::Coro
// This doubles up as our coroutine handle // This doubles up as our coroutine handle
auto coroData = coro::createCoroutineData(); auto coroData = coro::createCoroutineData();
coroData->useInternalScheduler = (marl::Scheduler::get() == nullptr);
if(coroData->useInternalScheduler)
{
::getOrCreateScheduler().bind();
}
marl::schedule([=] { marl::schedule([=] {
// Store handle in TLS so that the coroutine can grab it right away, before // Store handle in TLS so that the coroutine can grab it right away, before
// any fiber switch occurs. // any fiber switch occurs.
......
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