Skip to content

Commit 231eae5

Browse files
committed
Fix static deinitialization fiasco in destructor
Closes #4
1 parent eebb229 commit 231eae5

File tree

4 files changed

+35
-55
lines changed

4 files changed

+35
-55
lines changed

src/core/aql_profile.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#include "core/commandbuffermgr.hpp"
4343

4444
#define CONSTRUCTOR_API __attribute__((constructor))
45-
#define DESTRUCTOR_API __attribute__((destructor))
4645
#define ERR_CHECK(cond, err, msg) \
4746
{ \
4847
if (cond) { \
@@ -159,12 +158,8 @@ hsa_status_t DefaultTracedataCallback(hsa_ven_amd_aqlprofile_info_type_t info_ty
159158
return status;
160159
}
161160

162-
Logger::mutex_t Logger::mutex_;
163-
Logger* Logger::instance_ = NULL;
164161
bool Pm4Factory::concurrent_create_mode_ = false;
165162
bool Pm4Factory::spm_kfd_mode_ = false;
166-
Pm4Factory::mutex_t Pm4Factory::mutex_;
167-
Pm4Factory::instances_t* Pm4Factory::instances_ = NULL;
168163
bool read_api_enabled = true;
169164

170165
CONSTRUCTOR_API void constructor() {
@@ -174,11 +169,6 @@ CONSTRUCTOR_API void constructor() {
174169
}
175170
}
176171

177-
DESTRUCTOR_API void destructor() {
178-
Logger::Destroy();
179-
Pm4Factory::Destroy();
180-
}
181-
182172
} // namespace aql_profile
183173

184174
extern "C" {

src/core/logger.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,13 @@ class Logger {
6969

7070
static const std::string& LastMessage() {
7171
Logger& logger = Instance();
72-
std::lock_guard<mutex_t> lck(mutex_);
72+
std::lock_guard<mutex_t> lck(logger.mutex_);
7373
return logger.message_[GetTid()];
7474
}
7575

7676
static Logger& Instance() {
77-
std::lock_guard<mutex_t> lck(mutex_);
78-
if (instance_ == NULL) instance_ = new Logger();
79-
return *instance_;
80-
}
81-
82-
static void Destroy() {
83-
std::lock_guard<mutex_t> lck(mutex_);
84-
if (instance_ != NULL) delete instance_;
85-
instance_ = NULL;
77+
static Logger instance;
78+
return instance;
8679
}
8780

8881
private:
@@ -143,8 +136,7 @@ class Logger {
143136
bool streaming_;
144137
bool messaging_;
145138

146-
static mutex_t mutex_;
147-
static Logger* instance_;
139+
mutex_t mutex_;
148140
std::map<uint32_t, std::string> message_;
149141
};
150142

src/core/pm4_factory.h

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <climits>
3232
#include <map>
33+
#include <memory>
3334
#include <mutex>
3435
#include <sstream>
3536
#include <string>
@@ -119,8 +120,6 @@ class Pm4Factory {
119120
// First check and save the mode
120121
return Create(profile->agent, CheckConcurrent(profile));
121122
}
122-
// Destroy factory
123-
static void Destroy();
124123

125124
// Return gpu id
126125
gpu_id_t GetGpuId() const { return gpu_id_; }
@@ -227,6 +226,7 @@ class Pm4Factory {
227226
concurrent_mode_(concurrent_create_mode_),
228227
block_map_(map) {}
229228

229+
friend class std::default_delete<Pm4Factory>;
230230
virtual ~Pm4Factory() {
231231
delete cmd_builder_;
232232
delete pmc_builder_;
@@ -257,7 +257,7 @@ class Pm4Factory {
257257
return a.handle < b.handle;
258258
}
259259
};
260-
typedef std::map<hsa_agent_t, Pm4Factory*, instances_fncomp_t> instances_t;
260+
typedef std::map<hsa_agent_t, std::unique_ptr<Pm4Factory>, instances_fncomp_t> instances_t;
261261

262262
// Create GFX9 generic factory
263263
static Pm4Factory* Gfx9Create(const AgentInfo* agent_info);
@@ -280,19 +280,27 @@ class Pm4Factory {
280280

281281
static bool CheckConcurrent(const profile_t* profile);
282282

283-
// Mutex for inter thread synchronization for the instances create/destroy
284-
static mutex_t mutex_;
285-
// Factory instances container
286-
static instances_t* instances_;
283+
// This struct holds all the "global" state for the factory system
284+
struct Manager {
285+
// Mutex for inter thread synchronization for the instances create/destroy
286+
mutex_t mutex_;
287+
// Factory instances container
288+
instances_t instances_;
289+
};
290+
291+
static Manager& getManager() {
292+
static Manager manager_instance;
293+
return manager_instance;
294+
}
295+
287296
// Block info container
288297
const BlockInfoMap block_map_;
289298
};
290299

291300
inline Pm4Factory* Pm4Factory::Create(const AgentInfo* agent_info, gpu_id_t gpu_id,
292301
bool concurrent) {
293-
// Check if we have the instance already created
294-
if (instances_ == NULL) instances_ = new instances_t;
295-
const auto ret = instances_->insert({agent_info->dev_id, NULL});
302+
auto& manager = getManager();
303+
const auto ret = manager.instances_.insert({agent_info->dev_id, nullptr});
296304
instances_t::iterator it = ret.first;
297305

298306
concurrent_create_mode_ = concurrent;
@@ -301,48 +309,51 @@ inline Pm4Factory* Pm4Factory::Create(const AgentInfo* agent_info, gpu_id_t gpu_
301309

302310
// Create a factory implementation for the GPU id
303311
if (ret.second) {
312+
Pm4Factory *impl = nullptr;
304313
switch (gpu_id) {
305314
// Create Gfx9 generic factory
306315
case GFX9_GPU_ID:
307-
it->second = Gfx9Create(agent_info);
316+
impl = Gfx9Create(agent_info);
308317
break;
309318
// Create Gfx10 generic factory
310319
case GFX10_GPU_ID:
311-
it->second = Gfx10Create(agent_info);
320+
impl = Gfx10Create(agent_info);
312321
break;
313322
// Create Gfx11 generic factory
314323
case GFX11_GPU_ID:
315-
it->second = Gfx11Create(agent_info);
324+
impl = Gfx11Create(agent_info);
316325
break;
317326
case GFX12_GPU_ID:
318-
it->second = Gfx12Create(agent_info);
327+
impl = Gfx12Create(agent_info);
319328
break;
320329
// Create MI100 generic factory
321330
case MI100_GPU_ID:
322-
it->second = Mi100Create(agent_info);
331+
impl = Mi100Create(agent_info);
323332
break;
324333
case MI200_GPU_ID:
325-
it->second = Mi200Create(agent_info);
334+
impl = Mi200Create(agent_info);
326335
break;
327336
case MI300_GPU_ID:
328-
it->second = Mi300Create(agent_info);
337+
impl = Mi300Create(agent_info);
329338
break;
330339
case MI350_GPU_ID:
331-
it->second = Mi350Create(agent_info);
340+
impl = Mi350Create(agent_info);
332341
break;
333342
default:
334343
throw aql_profile_exc_val<gpu_id_t>("GPU id error", gpu_id);
335344
}
345+
it->second.reset(impl);
336346
}
337347

338348
if (it->second == NULL) throw aql_profile_exc_msg("Pm4Factory::Create() failed");
339349
it->second->gpu_id_ = gpu_id;
340-
return it->second;
350+
return it->second.get();
341351
}
342352

343353
// Create PM4 factory
344354
inline Pm4Factory* Pm4Factory::Create(const hsa_agent_t agent, bool concurrent) {
345-
std::lock_guard<mutex_t> lck(mutex_);
355+
auto& manager = getManager();
356+
std::lock_guard<mutex_t> lck(manager.mutex_);
346357
const AgentInfo* agent_info = HsaRsrcFactory::Instance().GetAgentInfo(agent);
347358
// Get GPU id for a given agent
348359

@@ -373,17 +384,6 @@ inline Pm4Factory* Pm4Factory::Create(aqlprofile_agent_handle_t agent_info, bool
373384
return Pm4Factory::Create(info, gpu_id, concurrent);
374385
}
375386

376-
// Destroy PM4 factory
377-
inline void Pm4Factory::Destroy() {
378-
std::lock_guard<mutex_t> lck(mutex_);
379-
380-
if (instances_ != NULL) {
381-
for (auto& item : *instances_) delete item.second;
382-
delete instances_;
383-
instances_ = NULL;
384-
}
385-
}
386-
387387
// Check the setting of pmc profiling mode
388388
inline bool Pm4Factory::CheckConcurrent(const profile_t* profile) {
389389
for (const hsa_ven_amd_aqlprofile_parameter_t* p = profile->parameters;

src/core/tests/aql_profile_tests.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ using namespace testing;
3838
namespace aql_profile {
3939
bool Pm4Factory::concurrent_create_mode_ = false;
4040
bool Pm4Factory::spm_kfd_mode_ = false;
41-
Pm4Factory::mutex_t Pm4Factory::mutex_;
42-
Pm4Factory::instances_t* Pm4Factory::instances_ = nullptr;
4341
}
4442

4543
// Mock classes to simulate Pm4Factory and related functionality

0 commit comments

Comments
 (0)