gfxstream: Use the Mesa common tss_* TLS helper functions

... in GfxstreamConnectionManager, to acquire the threadLocalInstance
of the connectionManager. Using thread_local attribute storage to store
some CPP primitives (i.e. unique_ptr) can cause issues on some
platforms.

Better to do all TLS as explicit as possible, using the available
utilities from common src/util. Don't need to wrap it in
a std::unique_ptr either, as the instance is just managed by the
destructor in the TLS interface.

Reviewed-by: Gurchetan Singh <gurchetansingh@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36302>
This commit is contained in:
Aaron Ruby 2025-07-22 17:41:37 -04:00 committed by Marge Bot
parent 5d55b7e50c
commit 4a30c6fd70
3 changed files with 52 additions and 31 deletions

View file

@ -12,15 +12,60 @@
#include "VirtGpu.h" #include "VirtGpu.h"
#include "VirtioGpuAddressSpaceStream.h" #include "VirtioGpuAddressSpaceStream.h"
#include "VirtioGpuPipeStream.h" #include "VirtioGpuPipeStream.h"
#include "c11/threads.h"
#include "util/log.h" #include "util/log.h"
#define STREAM_BUFFER_SIZE (4 * 1024 * 1024) #define STREAM_BUFFER_SIZE (4 * 1024 * 1024)
struct ThreadInfo { static tss_t gfxstream_connection_manager_tls_key;
std::unique_ptr<GfxStreamConnectionManager> mgr; static bool gfxstream_connection_manager_tls_key_valid;
};
static thread_local ThreadInfo sThreadInfo; static void gfxstream_connection_manager_tls_free(void* tls) {
if (tls) {
delete ((GfxStreamConnectionManager*)tls);
}
}
static void gfxstream_connection_manager_tls_key_create_once(void) {
gfxstream_connection_manager_tls_key_valid =
tss_create(&gfxstream_connection_manager_tls_key, gfxstream_connection_manager_tls_free) ==
thrd_success;
if (!gfxstream_connection_manager_tls_key_valid) {
mesa_loge("WARNING: failed to create gfxstream_connection_manager_tls_key");
}
}
GfxStreamConnectionManager* GfxStreamConnectionManager::getThreadLocalInstance(
GfxStreamTransportType type, VirtGpuCapset capset) {
static once_flag once = ONCE_FLAG_INIT;
call_once(&once, gfxstream_connection_manager_tls_key_create_once);
if (unlikely(!gfxstream_connection_manager_tls_key_valid)) {
return nullptr;
}
GfxStreamConnectionManager* tls =
(GfxStreamConnectionManager*)tss_get(gfxstream_connection_manager_tls_key);
if (likely(tls)) {
return tls;
}
tls = new GfxStreamConnectionManager(type, capset);
if (!tls) {
return nullptr;
}
if (!tls->initialize()) {
delete tls;
return nullptr;
}
if (tss_set(gfxstream_connection_manager_tls_key, tls) != thrd_success) {
delete tls;
return nullptr;
}
return tls;
}
GfxStreamConnectionManager::GfxStreamConnectionManager(GfxStreamTransportType type, GfxStreamConnectionManager::GfxStreamConnectionManager(GfxStreamTransportType type,
VirtGpuCapset capset) VirtGpuCapset capset)
@ -96,27 +141,6 @@ bool GfxStreamConnectionManager::initialize() {
return true; return true;
} }
GfxStreamConnectionManager* GfxStreamConnectionManager::getThreadLocalInstance(
GfxStreamTransportType type, VirtGpuCapset capset) {
if (sThreadInfo.mgr == nullptr) {
sThreadInfo.mgr = std::make_unique<GfxStreamConnectionManager>(type, capset);
if (!sThreadInfo.mgr->initialize()) {
sThreadInfo.mgr = nullptr;
return nullptr;
}
}
return sThreadInfo.mgr.get();
}
void GfxStreamConnectionManager::threadLocalExit() {
if (sThreadInfo.mgr == nullptr) {
return;
}
sThreadInfo.mgr.reset();
}
int32_t GfxStreamConnectionManager::addConnection(GfxStreamConnectionType type, int32_t GfxStreamConnectionManager::addConnection(GfxStreamConnectionType type,
std::unique_ptr<GfxStreamConnection> connection) { std::unique_ptr<GfxStreamConnection> connection) {
if (mConnections.find(type) != mConnections.end()) { if (mConnections.find(type) != mConnections.end()) {

View file

@ -29,12 +29,11 @@ enum GfxStreamTransportType {
class GfxStreamConnectionManager { class GfxStreamConnectionManager {
public: public:
GfxStreamConnectionManager(GfxStreamTransportType type, VirtGpuCapset capset);
~GfxStreamConnectionManager();
static GfxStreamConnectionManager* getThreadLocalInstance(GfxStreamTransportType type, static GfxStreamConnectionManager* getThreadLocalInstance(GfxStreamTransportType type,
VirtGpuCapset capset); VirtGpuCapset capset);
void threadLocalExit();
GfxStreamConnectionManager(GfxStreamTransportType type, VirtGpuCapset capset);
~GfxStreamConnectionManager();
bool initialize(); bool initialize();
int32_t addConnection(GfxStreamConnectionType type, int32_t addConnection(GfxStreamConnectionType type,

View file

@ -417,8 +417,6 @@ void gfxstream_vk_DestroyInstance(VkInstance _instance, const VkAllocationCallba
// To make End2EndTests happy, since now the host connection is statically linked to // To make End2EndTests happy, since now the host connection is statically linked to
// libvulkan_ranchu.so [separate HostConnections now]. // libvulkan_ranchu.so [separate HostConnections now].
#if defined(END2END_TESTS) #if defined(END2END_TESTS)
GfxStreamConnectionManager* mgr = getConnectionManager();
mgr->threadLocalExit();
VirtGpuDevice::resetInstance(); VirtGpuDevice::resetInstance();
gSeqno = 0; gSeqno = 0;
#endif #endif