12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_id_name_manager.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdlib.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/singleton.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base { 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kDefaultName[] = ""; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string* g_default_name; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ThreadIdNameManager::ThreadIdNameManager() 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : main_process_name_(NULL), 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) main_process_id_(kInvalidThreadId) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_default_name = new std::string(kDefaultName); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutoLock locked(lock_); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_to_interned_name_[kDefaultName] = g_default_name; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ThreadIdNameManager::~ThreadIdNameManager() { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ThreadIdNameManager* ThreadIdNameManager::GetInstance() { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Singleton<ThreadIdNameManager, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LeakySingletonTraits<ThreadIdNameManager> >::get(); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* ThreadIdNameManager::GetDefaultInternedString() { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_default_name->c_str(); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadIdNameManager::RegisterThread(PlatformThreadHandle::Handle handle, 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThreadId id) { 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AutoLock locked(lock_); 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_id_to_handle_[id] = handle; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_handle_to_interned_name_[handle] = 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) name_to_interned_name_[kDefaultName]; 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThreadIdNameManager::SetName(PlatformThreadId id, const char* name) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string str_name(name); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutoLock locked(lock_); 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NameToInternedNameMap::iterator iter = name_to_interned_name_.find(str_name); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* leaked_str = NULL; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != name_to_interned_name_.end()) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) leaked_str = iter->second; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) leaked_str = new std::string(str_name); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_to_interned_name_[str_name] = leaked_str; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadIdToHandleMap::iterator id_to_handle_iter = 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_id_to_handle_.find(id); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The main thread of a process will not be created as a Thread object which 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // means there is no PlatformThreadHandler registered. 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (id_to_handle_iter == thread_id_to_handle_.end()) { 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) main_process_name_ = leaked_str; 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) main_process_id_ = id; 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_handle_to_interned_name_[id_to_handle_iter->second] = leaked_str; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* ThreadIdNameManager::GetName(PlatformThreadId id) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutoLock locked(lock_); 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (id == main_process_id_) 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return main_process_name_->c_str(); 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadIdToHandleMap::iterator id_to_handle_iter = 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_id_to_handle_.find(id); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (id_to_handle_iter == thread_id_to_handle_.end()) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return name_to_interned_name_[kDefaultName]->c_str(); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadHandleToInternedNameMap::iterator handle_to_name_iter = 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_handle_to_interned_name_.find(id_to_handle_iter->second); 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return handle_to_name_iter->second->c_str(); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ThreadIdNameManager::RemoveName(PlatformThreadHandle::Handle handle, 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThreadId id) { 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AutoLock locked(lock_); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadHandleToInternedNameMap::iterator handle_to_name_iter = 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_handle_to_interned_name_.find(handle); 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(handle_to_name_iter != thread_handle_to_interned_name_.end()); 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_handle_to_interned_name_.erase(handle_to_name_iter); 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadIdToHandleMap::iterator id_to_handle_iter = 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_id_to_handle_.find(id); 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK((id_to_handle_iter!= thread_id_to_handle_.end())); 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The given |id| may have been re-used by the system. Make sure the 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // mapping points to the provided |handle| before removal. 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (id_to_handle_iter->second != handle) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_id_to_handle_.erase(id_to_handle_iter); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace base 114