OSDN Git Service

Add memory allocation statistics to the Bluetooth dumpsys output
authorPavlin Radoslavov <pavlin@google.com>
Wed, 1 Feb 2017 11:55:33 +0000 (03:55 -0800)
committerPavlin Radoslavov <pavlin@google.com>
Wed, 1 Feb 2017 12:00:54 +0000 (04:00 -0800)
The following memory allocation statistics are added to
the "dumpsys bluetooth_manager" output.
Those are tracking the allocations that are using the OSI malloc mechanism:
osi_strdup() / osi_strndup() / osi_malloc() / osi_calloc() / osi_free()

Bluetooth Memory Allocation Statistics:
  Total allocated/free/used counts : 4063 / 3323 / 740
  Total allocated/free/used octets : 922460 / 607941 / 314519

Test: Running "adb shell dumpsys bluetooth_manager"
Change-Id: Ibe1d28ec3a2acfd87cfaa10e5902ef3b596e64a8

btif/src/bluetooth.cc
osi/include/allocator.h
osi/src/allocation_tracker.cc

index 085453f..408d184 100644 (file)
@@ -309,6 +309,7 @@ static void dump(int fd, const char** arguments) {
   btif_debug_config_dump(fd);
   BTA_HfClientDumpStatistics(fd);
   wakelock_debug_dump(fd);
+  osi_allocator_debug_dump(fd);
   alarm_debug_dump(fd);
 #if (BTSNOOP_MEM == TRUE)
   btif_debug_btsnoop_dump(fd);
index 890722b..ef03f9a 100644 (file)
@@ -46,3 +46,8 @@ void osi_free(void* ptr);
 // |p_ptr| is a pointer to the buffer pointer to be reset.
 // |p_ptr| cannot be NULL.
 void osi_free_and_reset(void** p_ptr);
+
+// Dump allocation-related statistics and debug info to the |fd| file
+// descriptor.
+// The information is in user-readable text format. The |fd| must be valid.
+void osi_allocator_debug_dump(int fd);
index 78bd259..461e342 100644 (file)
@@ -43,6 +43,12 @@ static std::unordered_map<void*, allocation_t*> allocations;
 static std::mutex tracker_lock;
 static bool enabled = false;
 
+// Memory allocation statistics
+static size_t alloc_counter = 0;
+static size_t free_counter = 0;
+static size_t alloc_total_size = 0;
+static size_t free_total_size = 0;
+
 void allocation_tracker_init(void) {
   std::unique_lock<std::mutex> lock(tracker_lock);
   if (enabled) return;
@@ -98,6 +104,10 @@ void* allocation_tracker_notify_alloc(uint8_t allocator_id, void* ptr,
     std::unique_lock<std::mutex> lock(tracker_lock);
     if (!enabled || !ptr) return ptr;
 
+    // Keep statistics
+    alloc_counter++;
+    alloc_total_size += allocation_tracker_resize_for_canary(requested_size);
+
     return_ptr = ((char*)ptr) + canary_size;
 
     auto map_entry = allocations.find(return_ptr);
@@ -126,6 +136,7 @@ void* allocation_tracker_notify_alloc(uint8_t allocator_id, void* ptr,
 void* allocation_tracker_notify_free(UNUSED_ATTR uint8_t allocator_id,
                                      void* ptr) {
   std::unique_lock<std::mutex> lock(tracker_lock);
+
   if (!enabled || !ptr) return ptr;
 
   auto map_entry = allocations.find(ptr);
@@ -135,6 +146,11 @@ void* allocation_tracker_notify_free(UNUSED_ATTR uint8_t allocator_id,
   CHECK(!allocation->freed);  // Must not be a double free
   CHECK(allocation->allocator_id ==
         allocator_id);  // Must be from the same allocator
+
+  // Keep statistics
+  free_counter++;
+  free_total_size += allocation_tracker_resize_for_canary(allocation->size);
+
   allocation->freed = true;
 
   UNUSED_ATTR const char* beginning_canary = ((char*)ptr) - canary_size;
@@ -156,3 +172,15 @@ void* allocation_tracker_notify_free(UNUSED_ATTR uint8_t allocator_id,
 size_t allocation_tracker_resize_for_canary(size_t size) {
   return (!enabled) ? size : size + (2 * canary_size);
 }
+
+void osi_allocator_debug_dump(int fd) {
+  dprintf(fd, "\nBluetooth Memory Allocation Statistics:\n");
+
+  std::unique_lock<std::mutex> lock(tracker_lock);
+
+  dprintf(fd, "  Total allocated/free/used counts : %zu / %zu / %zu\n",
+          alloc_counter, free_counter, alloc_counter - free_counter);
+  dprintf(fd, "  Total allocated/free/used octets : %zu / %zu / %zu\n",
+          alloc_total_size, free_total_size,
+          alloc_total_size - free_total_size);
+}