diff options
author | Michael Yu <warty@google.com> | 2021-05-03 11:54:52 -0700 |
---|---|---|
committer | Michael Yu <warty@google.com> | 2021-05-03 12:40:40 -0700 |
commit | ac36396038bbf135dc9549fe511b8f3d087faec4 (patch) | |
tree | ada9cf83e640b59124e4a6b683b166669b49c372 | |
parent | 679c6dd5cfed65994b3dd526c283d87277ac5c80 (diff) | |
download | vulkan-cereal-ac36396038bbf135dc9549fe511b8f3d087faec4.tar.gz |
Reenable multiple syncthreads
Prior, enabling multiple syncthreads caused a stream of
eglClientWaitSync errors. SyncThread::initSyncContext was only telling a
single worker thread to SYNC_THREAD_INIT. Other workers weren't
initializing their EGL contexts, so on those threads invoking
FenceSync::wait would fail in the GT_CTX_V2_RET of GLESv30Imp.cpp's
internal_glClientWaitSync because of a lack of thread context, returning
GL_WAIT_FAILED (without setting the last error!).
As a minimal workaround, this change dispatches a command for each
worker in the pool, which works because the underlying job-assignment
strategy for worker thread commands is round-robin.
Additionally, amends the abnormal exit error log with eglGetError().
Bug: 186146855
Test: Verify no more nonstop abnormal exit errors.
Change-Id: I2c8772b20551a863a262bc6ebc12028a959808fe
-rw-r--r-- | base/ThreadPool.h | 1 | ||||
-rw-r--r-- | stream-servers/SyncThread.cpp | 17 |
2 files changed, 12 insertions, 6 deletions
diff --git a/base/ThreadPool.h b/base/ThreadPool.h index ceacd10e..f21a628d 100644 --- a/base/ThreadPool.h +++ b/base/ThreadPool.h @@ -121,6 +121,7 @@ public: void enqueue(Item&& item) { // Iterate over the worker threads until we find a one that's running. + // TODO(b/187082169, warty): We rely on this round-robin strategy in SyncThread for (;;) { int currentIndex = mNextWorkerIndex.fetch_add(1, std::memory_order_relaxed); diff --git a/stream-servers/SyncThread.cpp b/stream-servers/SyncThread.cpp index 1b3e0e74..f0744294 100644 --- a/stream-servers/SyncThread.cpp +++ b/stream-servers/SyncThread.cpp @@ -66,7 +66,7 @@ static GlobalSyncThread* sGlobalSyncThread() { static const uint32_t kTimelineInterval = 1; static const uint64_t kDefaultTimeoutNsecs = 5ULL * 1000ULL * 1000ULL * 1000ULL; -static const uint64_t kNumWorkerThreads = 1u; +static const uint64_t kNumWorkerThreads = 4u; SyncThread::SyncThread() : android::base::Thread(android::base::ThreadFlags::MaskSignals, 512 * 1024), @@ -132,9 +132,13 @@ void SyncThread::cleanup() { void SyncThread::initSyncContext() { DPRINT("enter"); - SyncThreadCmd to_send; - to_send.opCode = SYNC_THREAD_INIT; - sendAndWaitForResult(to_send); + // TODO(b/187082169, warty): The thread pool's command-assignment strategy + // is round-robin, so as a hack, create one command for each worker. + for (int i = 0; i < mWorkerThreadPool.numWorkers(); i++) { + SyncThreadCmd to_send; + to_send.opCode = SYNC_THREAD_INIT; + sendAndWaitForResult(to_send); + } DPRINT("exit"); } @@ -313,8 +317,9 @@ void SyncThread::doSyncBlockedWaitNoTimeline(SyncThreadCmd* cmd) { wait_result); if (wait_result != EGL_CONDITION_SATISFIED_KHR) { - fprintf(stderr, "error: eglClientWaitSync abnormal exit 0x%x %p\n", - wait_result, cmd->fenceSync); + EGLint error = s_egl.eglGetError(); + fprintf(stderr, "error: eglClientWaitSync abnormal exit 0x%x %p %#x\n", + wait_result, cmd->fenceSync, error); } } |