RecordData.cpp revision 2b2b25b87827102671cdd4b25c01aa22a9971a63
17bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris/* 27bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * Copyright (C) 2016 The Android Open Source Project 37bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * All rights reserved. 47bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * 57bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * Redistribution and use in source and binary forms, with or without 67bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * modification, are permitted provided that the following conditions 77bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * are met: 87bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * * Redistributions of source code must retain the above copyright 97bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * notice, this list of conditions and the following disclaimer. 107bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * * Redistributions in binary form must reproduce the above copyright 117bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * notice, this list of conditions and the following disclaimer in 127bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * the documentation and/or other materials provided with the 137bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * distribution. 147bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * 157bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 167bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 177bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 187bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 197bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 207bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 217bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 227bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 237bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 247bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 257bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 267bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris * SUCH DAMAGE. 277bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris */ 287bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 297bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <errno.h> 307bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <fcntl.h> 317bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <pthread.h> 327bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <stdatomic.h> 337bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <stdint.h> 347bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <stdio.h> 357bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <stdlib.h> 367bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <sys/types.h> 377bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 387bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <mutex> 397bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 407bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include <android-base/stringprintf.h> 417bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 427bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include "Config.h" 437bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include "debug_disable.h" 447bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include "debug_log.h" 457bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include "DebugData.h" 467bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris#include "RecordData.h" 477bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 487bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisRecordEntry::RecordEntry() : tid_(gettid()) { 497bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 507bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 517bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstd::string ThreadCompleteEntry::GetString() const { 527bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return android::base::StringPrintf("%d: thread_done 0x0\n", tid_); 537bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 547bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 557bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisAllocEntry::AllocEntry(void* pointer) : pointer_(pointer) { 567bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 577bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 587bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisMallocEntry::MallocEntry(void* pointer, size_t size) : AllocEntry(pointer), size_(size) { 597bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 607bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 617bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstd::string MallocEntry::GetString() const { 627bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return android::base::StringPrintf("%d: malloc %p %zu\n", tid_, pointer_, size_); 637bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 647bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 657bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisFreeEntry::FreeEntry(void* pointer) : AllocEntry(pointer) { 667bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 677bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 687bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstd::string FreeEntry::GetString() const { 697bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return android::base::StringPrintf("%d: free %p\n", tid_, pointer_); 707bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 717bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 727bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisCallocEntry::CallocEntry(void* pointer, size_t nmemb, size_t size) 737bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris : MallocEntry(pointer, size), nmemb_(nmemb) { 747bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 757bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 767bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstd::string CallocEntry::GetString() const { 777bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return android::base::StringPrintf("%d: calloc %p %zu %zu\n", tid_, pointer_, nmemb_, size_); 787bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 797bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 807bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisReallocEntry::ReallocEntry(void* pointer, size_t size, void* old_pointer) 817bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris : MallocEntry(pointer, size), old_pointer_(old_pointer) { 827bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 837bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 847bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstd::string ReallocEntry::GetString() const { 857bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return android::base::StringPrintf("%d: realloc %p %p %zu\n", tid_, pointer_, 867bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris old_pointer_, size_); 877bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 887bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 897bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris// posix_memalign, memalgin, pvalloc, valloc all recorded with this class. 907bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisMemalignEntry::MemalignEntry(void* pointer, size_t size, size_t alignment) 917bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris : MallocEntry(pointer, size), alignment_(alignment) { 927bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 937bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 947bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstd::string MemalignEntry::GetString() const { 957bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return android::base::StringPrintf("%d: memalign %p %zu %zu\n", tid_, pointer_, 967bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris alignment_, size_); 977bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 987bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 997bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstruct ThreadData { 1007bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris ThreadData(RecordData* record_data, ThreadCompleteEntry* entry) : record_data(record_data), entry(entry) {} 1017bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris RecordData* record_data; 1027bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris ThreadCompleteEntry* entry; 1037bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris size_t count = 0; 1047bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris}; 1057bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1067bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstatic void ThreadKeyDelete(void* data) { 1077bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris ThreadData* thread_data = reinterpret_cast<ThreadData*>(data); 1087bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1097bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris thread_data->count++; 1107bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1117bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // This should be the last time we are called. 1127bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (thread_data->count == 4) { 1137bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris ScopedDisableDebugCalls disable; 1147bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1157bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris thread_data->record_data->AddEntryOnly(thread_data->entry); 1167bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris delete thread_data; 1177bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } else { 1187bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris pthread_setspecific(thread_data->record_data->key(), data); 1197bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1207bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 1217bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1227bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisstatic void RecordDump(int, siginfo_t*, void*) { 1237bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // It's not necessarily safe to do the dump here, instead wait for the 1247bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // next allocation call to do the dump. 1257bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris g_debug->record->SetToDump(); 1267bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 1277bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1287bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisvoid RecordData::Dump() { 1297bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris std::lock_guard<std::mutex> lock(dump_lock_); 1307bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1317bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // Make it so that no more entries can be added while dumping. 1327bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris unsigned int last_entry_index = cur_index_.exchange(static_cast<unsigned int>(num_entries_)); 1337bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (dump_ == false) { 1347bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // Multiple Dump() calls from different threads, and we lost. Do nothing. 1357bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return; 1367bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1377bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1387bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // cur_index_ keeps getting incremented even if we hit the num_entries_. 1397bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // If that happens, cap the entries to dump by num_entries_. 1407bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (last_entry_index > num_entries_) { 1417bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris last_entry_index = num_entries_; 1427bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1437bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1447bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris int dump_fd = open(dump_file_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, 1457bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 0755); 1467bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (dump_fd != -1) { 1477bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris for (size_t i = 0; i < last_entry_index; i++) { 1487bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris std::string line = entries_[i]->GetString(); 1497bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris ssize_t bytes = write(dump_fd, line.c_str(), line.length()); 1507bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (bytes == -1 || static_cast<size_t>(bytes) != line.length()) { 1517bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris error_log("Failed to write record alloc information: %s", strerror(errno)); 1527bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // Free all of the rest of the errors, we don't have any way 1537bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // to dump a partial list of the entries. 1547bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris for (i++; i < last_entry_index; i++) { 1557bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris delete entries_[i]; 1567bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris entries_[i] = nullptr; 1577bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1587bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris break; 1597bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1607bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris delete entries_[i]; 1617bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris entries_[i] = nullptr; 1627bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1637bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris close(dump_fd); 1647bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1657bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // Mark the entries dumped. 1667bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris cur_index_ = 0U; 1677bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } else { 1687bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris error_log("Cannot create record alloc file %s: %s", dump_file_.c_str(), strerror(errno)); 1697bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // Since we couldn't create the file, reset the entries dumped back 1707bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // to the original value. 1717bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris cur_index_ = last_entry_index; 1727bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1737bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1747bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris dump_ = false; 1757bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 1767bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1777bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisRecordData::RecordData() { 1787bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris pthread_key_create(&key_, ThreadKeyDelete); 1797bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 1807bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1817bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisbool RecordData::Initialize(const Config& config) { 1827bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris struct sigaction dump_act; 1837bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris memset(&dump_act, 0, sizeof(dump_act)); 1847bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1857bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris dump_act.sa_sigaction = RecordDump; 1867bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris dump_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 1877bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris sigemptyset(&dump_act.sa_mask); 1882b2b25b87827102671cdd4b25c01aa22a9971a63Christopher Ferris if (sigaction(config.record_allocs_signal(), &dump_act, nullptr) != 0) { 1897bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris error_log("Unable to set up record dump signal function: %s", strerror(errno)); 1907bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return false; 1917bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 1927bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris pthread_setspecific(key_, nullptr); 1937bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1947bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris info_log("%s: Run: 'kill -%d %d' to dump the allocation records.", getprogname(), 1952b2b25b87827102671cdd4b25c01aa22a9971a63Christopher Ferris config.record_allocs_signal(), getpid()); 1967bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 1972b2b25b87827102671cdd4b25c01aa22a9971a63Christopher Ferris num_entries_ = config.record_allocs_num_entries(); 1987bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris entries_ = new const RecordEntry*[num_entries_]; 1997bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris cur_index_ = 0; 2007bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris dump_ = false; 2012b2b25b87827102671cdd4b25c01aa22a9971a63Christopher Ferris dump_file_ = config.record_allocs_file(); 2027bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 2037bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris return true; 2047bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 2057bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 2067bd01783a830f72c1245c262a7fd9a199e90aed1Christopher FerrisRecordData::~RecordData() { 2077bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris delete [] entries_; 2087bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris pthread_key_delete(key_); 2097bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 2107bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 2117bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisvoid RecordData::AddEntryOnly(const RecordEntry* entry) { 2127bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris unsigned int entry_index = cur_index_.fetch_add(1); 2137bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (entry_index < num_entries_) { 2147bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris entries_[entry_index] = entry; 2157bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 2167bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 2177bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 2187bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferrisvoid RecordData::AddEntry(const RecordEntry* entry) { 2197bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris void* data = pthread_getspecific(key_); 2207bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (data == nullptr) { 2217bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris ThreadData* thread_data = new ThreadData(this, new ThreadCompleteEntry()); 2227bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris pthread_setspecific(key_, thread_data); 2237bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 2247bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 2257bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris AddEntryOnly(entry); 2267bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris 2277bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris // Check to see if it's time to dump the entries. 2287bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris if (dump_) { 2297bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris Dump(); 2307bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris } 2317bd01783a830f72c1245c262a7fd9a199e90aed1Christopher Ferris} 232