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
291300inline 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
344354inline 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
388388inline bool Pm4Factory::CheckConcurrent (const profile_t * profile) {
389389 for (const hsa_ven_amd_aqlprofile_parameter_t * p = profile->parameters ;
0 commit comments