tools/profiler/GeckoTaskTracer.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "GeckoTaskTracer.h"
     8 #include "GeckoTaskTracerImpl.h"
    10 #include "mozilla/StaticMutex.h"
    11 #include "mozilla/ThreadLocal.h"
    12 #include "mozilla/unused.h"
    14 #include "nsClassHashtable.h"
    15 #include "nsThreadUtils.h"
    17 #include <stdarg.h>
    18 #include <stdio.h>
    19 #include <unistd.h>
    21 #if defined(__GLIBC__)
    22 // glibc doesn't implement gettid(2).
    23 #include <sys/syscall.h>
    24 static pid_t gettid()
    25 {
    26   return (pid_t) syscall(SYS_gettid);
    27 }
    28 #endif
    30 #define MAX_USER_LABEL_LEN 512
    32 namespace mozilla {
    33 namespace tasktracer {
    35 static mozilla::ThreadLocal<TraceInfo*> sTraceInfoTLS;
    36 static StaticMutex sMutex;
    37 static nsClassHashtable<nsUint32HashKey, TraceInfo>* sTraceInfos = nullptr;
    39 namespace {
    41 static TraceInfo*
    42 AllocTraceInfo(int aTid)
    43 {
    44   StaticMutexAutoLock lock(sMutex);
    46   sTraceInfos->Put(aTid, new TraceInfo(aTid));
    47   return sTraceInfos->Get(aTid);
    48 }
    50 static void
    51 FreeTraceInfo(int aTid)
    52 {
    53   StaticMutexAutoLock lock(sMutex);
    55   sTraceInfos->Remove(aTid);
    56 }
    58 static bool
    59 IsInitialized()
    60 {
    61   return sTraceInfoTLS.initialized();
    62 }
    64 static void
    65 SaveCurTraceInfo()
    66 {
    67   TraceInfo* info = GetOrCreateTraceInfo();
    68   NS_ENSURE_TRUE_VOID(info);
    70   info->mSavedCurTraceSourceId = info->mCurTraceSourceId;
    71   info->mSavedCurTraceSourceType = info->mCurTraceSourceType;
    72   info->mSavedCurTaskId = info->mCurTaskId;
    73 }
    75 static void
    76 RestoreCurTraceInfo()
    77 {
    78   TraceInfo* info = GetOrCreateTraceInfo();
    79   NS_ENSURE_TRUE_VOID(info);
    81   info->mCurTraceSourceId = info->mSavedCurTraceSourceId;
    82   info->mCurTraceSourceType = info->mSavedCurTraceSourceType;
    83   info->mCurTaskId = info->mSavedCurTaskId;
    84 }
    86 static void
    87 CreateSourceEvent(SourceEventType aType)
    88 {
    89   NS_ENSURE_TRUE_VOID(IsInitialized());
    91   // Save the currently traced source event info.
    92   SaveCurTraceInfo();
    94   // Create a new unique task id.
    95   uint64_t newId = GenNewUniqueTaskId();
    96   TraceInfo* info = GetOrCreateTraceInfo();
    97   info->mCurTraceSourceId = newId;
    98   info->mCurTraceSourceType = aType;
    99   info->mCurTaskId = newId;
   101   // Log a fake dispatch and start for this source event.
   102   LogDispatch(newId, newId,newId, aType);
   103   LogBegin(newId, newId);
   104 }
   106 static void
   107 DestroySourceEvent()
   108 {
   109   NS_ENSURE_TRUE_VOID(IsInitialized());
   111   // Log a fake end for this source event.
   112   TraceInfo* info = GetOrCreateTraceInfo();
   113   LogEnd(info->mCurTraceSourceId, info->mCurTraceSourceId);
   115   // Restore the previously saved source event info.
   116   RestoreCurTraceInfo();
   117 }
   119 } // namespace anonymous
   121 void
   122 InitTaskTracer()
   123 {
   124   MOZ_ASSERT(!sTraceInfos);
   126   sTraceInfos = new nsClassHashtable<nsUint32HashKey, TraceInfo>();
   128   if (!sTraceInfoTLS.initialized()) {
   129     unused << sTraceInfoTLS.init();
   130   }
   131 }
   133 void
   134 ShutdownTaskTracer()
   135 {
   136   delete sTraceInfos;
   137   sTraceInfos = nullptr;
   138 }
   140 TraceInfo*
   141 GetOrCreateTraceInfo()
   142 {
   143   NS_ENSURE_TRUE(IsInitialized(), nullptr);
   145   TraceInfo* info = sTraceInfoTLS.get();
   146   if (!info) {
   147     info = AllocTraceInfo(gettid());
   148     sTraceInfoTLS.set(info);
   149   }
   151   return info;
   152 }
   154 uint64_t
   155 GenNewUniqueTaskId()
   156 {
   157   TraceInfo* info = GetOrCreateTraceInfo();
   158   NS_ENSURE_TRUE(info, 0);
   160   pid_t tid = gettid();
   161   uint64_t taskid = ((uint64_t)tid << 32) | ++info->mLastUniqueTaskId;
   162   return taskid;
   163 }
   165 AutoSaveCurTraceInfo::AutoSaveCurTraceInfo()
   166 {
   167   SaveCurTraceInfo();
   168 }
   170 AutoSaveCurTraceInfo::~AutoSaveCurTraceInfo()
   171 {
   172   RestoreCurTraceInfo();
   173 }
   175 void
   176 SetCurTraceInfo(uint64_t aSourceEventId, uint64_t aParentTaskId,
   177                 SourceEventType aSourceEventType)
   178 {
   179   TraceInfo* info = GetOrCreateTraceInfo();
   180   NS_ENSURE_TRUE_VOID(info);
   182   info->mCurTraceSourceId = aSourceEventId;
   183   info->mCurTaskId = aParentTaskId;
   184   info->mCurTraceSourceType = aSourceEventType;
   185 }
   187 void
   188 GetCurTraceInfo(uint64_t* aOutSourceEventId, uint64_t* aOutParentTaskId,
   189                 SourceEventType* aOutSourceEventType)
   190 {
   191   TraceInfo* info = GetOrCreateTraceInfo();
   192   NS_ENSURE_TRUE_VOID(info);
   194   *aOutSourceEventId = info->mCurTraceSourceId;
   195   *aOutParentTaskId = info->mCurTaskId;
   196   *aOutSourceEventType = info->mCurTraceSourceType;
   197 }
   199 void
   200 LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId, uint64_t aSourceEventId,
   201             SourceEventType aSourceEventType)
   202 {
   203   NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId);
   205   // Log format:
   206   // [0 taskId dispatchTime sourceEventId sourceEventType parentTaskId]
   207 }
   209 void
   210 LogBegin(uint64_t aTaskId, uint64_t aSourceEventId)
   211 {
   212   NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId);
   214   // Log format:
   215   // [1 taskId beginTime processId threadId]
   216 }
   218 void
   219 LogEnd(uint64_t aTaskId, uint64_t aSourceEventId)
   220 {
   221   NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId);
   223   // Log format:
   224   // [2 taskId endTime]
   225 }
   227 void
   228 LogVirtualTablePtr(uint64_t aTaskId, uint64_t aSourceEventId, int* aVptr)
   229 {
   230   NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId);
   232   // Log format:
   233   // [4 taskId address]
   234 }
   236 void
   237 FreeTraceInfo()
   238 {
   239   NS_ENSURE_TRUE_VOID(IsInitialized());
   241   FreeTraceInfo(gettid());
   242 }
   244 AutoSourceEvent::AutoSourceEvent(SourceEventType aType)
   245 {
   246   CreateSourceEvent(aType);
   247 }
   249 AutoSourceEvent::~AutoSourceEvent()
   250 {
   251   DestroySourceEvent();
   252 }
   254 void AddLabel(const char* aFormat, ...)
   255 {
   256   NS_ENSURE_TRUE_VOID(IsInitialized());
   258   va_list args;
   259   va_start(args, aFormat);
   260   char buffer[MAX_USER_LABEL_LEN] = {0};
   261   vsnprintf(buffer, MAX_USER_LABEL_LEN, aFormat, args);
   262   va_end(args);
   264   // Log format:
   265   // [3 taskId "label"]
   266 }
   268 } // namespace tasktracer
   269 } // namespace mozilla

mercurial