fix: Resolve a TSan warning for OpenGLTimerQuery (#9790)
The main thread invokes `getTimerQueryValue` synchronously, reading `tq->state`. Meanwhile, the driver thread handles `createTimerQuery` asynchronously and initializes `tq->state = std::make_shared<State>()`. Eliminate this race by initializing the state in createTimerQueryS. BUGS=[491522442]
This commit is contained in:
@@ -716,7 +716,11 @@ Handle<HwSwapChain> OpenGLDriver::createSwapChainHeadlessS() noexcept {
|
||||
}
|
||||
|
||||
Handle<HwTimerQuery> OpenGLDriver::createTimerQueryS() noexcept {
|
||||
return initHandle<GLTimerQuery>();
|
||||
Handle<HwTimerQuery> tqh = initHandle<GLTimerQuery>();
|
||||
// The state must be constructed here, as a synchronous call to getTimerQueryValue might happen
|
||||
// before createTimerQueryR is executed on the backend thread.
|
||||
handle_cast<GLTimerQuery*>(tqh)->state = std::make_shared<GLTimerQuery::State>();
|
||||
return tqh;
|
||||
}
|
||||
|
||||
Handle<HwDescriptorSetLayout> OpenGLDriver::createDescriptorSetLayoutS() noexcept {
|
||||
|
||||
@@ -88,15 +88,14 @@ TimerQueryFactoryInterface::~TimerQueryFactoryInterface() = default;
|
||||
// This is a backend synchronous call
|
||||
TimerQueryResult TimerQueryFactoryInterface::getTimerQueryValue(
|
||||
GLTimerQuery* tq, uint64_t* elapsedTime) noexcept {
|
||||
if (UTILS_LIKELY(tq->state)) {
|
||||
int64_t const elapsed = tq->state->elapsed.load(std::memory_order_relaxed);
|
||||
if (elapsed > 0) {
|
||||
*elapsedTime = elapsed;
|
||||
return TimerQueryResult::AVAILABLE;
|
||||
}
|
||||
return TimerQueryResult(elapsed);
|
||||
assert_invariant(tq->state);
|
||||
|
||||
int64_t const elapsed = tq->state->elapsed.load(std::memory_order_relaxed);
|
||||
if (elapsed > 0) {
|
||||
*elapsedTime = elapsed;
|
||||
return TimerQueryResult::AVAILABLE;
|
||||
}
|
||||
return TimerQueryResult::ERROR;
|
||||
return TimerQueryResult(elapsed);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -110,9 +109,8 @@ TimerQueryNativeFactory::TimerQueryNativeFactory(OpenGLContext& context)
|
||||
TimerQueryNativeFactory::~TimerQueryNativeFactory() = default;
|
||||
|
||||
void TimerQueryNativeFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(!tq->state);
|
||||
assert_invariant(tq->state);
|
||||
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
mContext.procs.genQueries(1u, &tq->state->gl.query);
|
||||
CHECK_GL_ERROR()
|
||||
}
|
||||
@@ -181,8 +179,7 @@ TimerQueryFenceFactory::~TimerQueryFenceFactory() {
|
||||
}
|
||||
|
||||
void TimerQueryFenceFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(!tq->state);
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
assert_invariant(tq->state);
|
||||
}
|
||||
|
||||
void TimerQueryFenceFactory::destroyTimerQuery(GLTimerQuery* tq) {
|
||||
@@ -238,8 +235,7 @@ TimerQueryFallbackFactory::TimerQueryFallbackFactory() = default;
|
||||
TimerQueryFallbackFactory::~TimerQueryFallbackFactory() = default;
|
||||
|
||||
void TimerQueryFallbackFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(!tq->state);
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
assert_invariant(tq->state);
|
||||
}
|
||||
|
||||
void TimerQueryFallbackFactory::destroyTimerQuery(GLTimerQuery* tq) {
|
||||
|
||||
Reference in New Issue
Block a user