LCOV - code coverage report
Current view: top level - tools/profiler/core - ProfilerMarker.h (source / functions) Hit Total Coverage
Test: output.info Lines: 12 57 21.1 %
Date: 2017-07-14 16:53:18 Functions: 4 14 28.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       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/. */
       6             : 
       7             : #ifndef ProfilerMarker_h
       8             : #define ProfilerMarker_h
       9             : 
      10             : #include "mozilla/UniquePtrExtensions.h"
      11             : 
      12             : #include "ProfilerMarkerPayload.h"
      13             : 
      14             : template<typename T>
      15             : class ProfilerLinkedList;
      16             : class SpliceableJSONWriter;
      17             : class UniqueStacks;
      18             : 
      19           0 : class ProfilerMarker
      20             : {
      21             :   friend class ProfilerLinkedList<ProfilerMarker>;
      22             : 
      23             : public:
      24           0 :   explicit ProfilerMarker(const char* aMarkerName,
      25             :                           mozilla::UniquePtr<ProfilerMarkerPayload>
      26             :                             aPayload = nullptr,
      27             :                           double aTime = 0)
      28           0 :     : mMarkerName(strdup(aMarkerName))
      29           0 :     , mPayload(Move(aPayload))
      30           0 :     , mTime(aTime)
      31           0 :   {}
      32             : 
      33           0 :   void SetGeneration(uint32_t aGenID) { mGenID = aGenID; }
      34             : 
      35           0 :   bool HasExpired(uint32_t aGenID) const { return mGenID + 2 <= aGenID; }
      36             : 
      37           0 :   double GetTime() const { return mTime; }
      38             : 
      39           0 :   void StreamJSON(SpliceableJSONWriter& aWriter,
      40             :                   const mozilla::TimeStamp& aProcessStartTime,
      41             :                   UniqueStacks& aUniqueStacks) const
      42             :   {
      43             :     // Schema:
      44             :     //   [name, time, data]
      45             : 
      46           0 :     aWriter.StartArrayElement();
      47             :     {
      48           0 :       aUniqueStacks.mUniqueStrings.WriteElement(aWriter, mMarkerName.get());
      49           0 :       aWriter.DoubleElement(mTime);
      50             :       // TODO: Store the callsite for this marker if available:
      51             :       // if have location data
      52             :       //   b.NameValue(marker, "location", ...);
      53           0 :       if (mPayload) {
      54           0 :         aWriter.StartObjectElement();
      55             :         {
      56           0 :           mPayload->StreamPayload(aWriter, aProcessStartTime, aUniqueStacks);
      57             :         }
      58           0 :         aWriter.EndObject();
      59             :       }
      60             :     }
      61           0 :     aWriter.EndArray();
      62           0 :   }
      63             : 
      64             : private:
      65             :   mozilla::UniqueFreePtr<char> mMarkerName;
      66             :   mozilla::UniquePtr<ProfilerMarkerPayload> mPayload;
      67             :   ProfilerMarker* mNext;
      68             :   double mTime;
      69             :   uint32_t mGenID;
      70             : };
      71             : 
      72             : template<typename T>
      73             : class ProfilerLinkedList
      74             : {
      75             : public:
      76          75 :   ProfilerLinkedList()
      77             :     : mHead(nullptr)
      78          75 :     , mTail(nullptr)
      79          75 :   {}
      80             : 
      81           0 :   void insert(T* aElem)
      82             :   {
      83           0 :     if (!mTail) {
      84           0 :       mHead = aElem;
      85           0 :       mTail = aElem;
      86             :     } else {
      87           0 :       mTail->mNext = aElem;
      88           0 :       mTail = aElem;
      89             :     }
      90           0 :     aElem->mNext = nullptr;
      91           0 :   }
      92             : 
      93           0 :   T* popHead()
      94             :   {
      95           0 :     if (!mHead) {
      96           0 :       MOZ_ASSERT(false);
      97             :       return nullptr;
      98             :     }
      99             : 
     100           0 :     T* head = mHead;
     101             : 
     102           0 :     mHead = head->mNext;
     103           0 :     if (!mHead) {
     104           0 :       mTail = nullptr;
     105             :     }
     106             : 
     107           0 :     return head;
     108             :   }
     109             : 
     110           1 :   const T* peek() {
     111           1 :     return mHead;
     112             :   }
     113             : 
     114             : private:
     115             :   T* mHead;
     116             :   T* mTail;
     117             : };
     118             : 
     119             : typedef ProfilerLinkedList<ProfilerMarker> ProfilerMarkerLinkedList;
     120             : 
     121             : template<typename T>
     122             : class ProfilerSignalSafeLinkedList
     123             : {
     124             : public:
     125          75 :   ProfilerSignalSafeLinkedList()
     126          75 :     : mSignalLock(false)
     127          75 :   {}
     128             : 
     129           1 :   ~ProfilerSignalSafeLinkedList()
     130             :   {
     131           1 :     if (mSignalLock) {
     132             :       // Some thread is modifying the list. We should only be released on that
     133             :       // thread.
     134           0 :       abort();
     135             :     }
     136             : 
     137           1 :     while (mList.peek()) {
     138           0 :       delete mList.popHead();
     139             :     }
     140           1 :   }
     141             : 
     142             :   // Insert an item into the list. Must only be called from the owning thread.
     143             :   // Must not be called while the list from accessList() is being accessed.
     144             :   // In the profiler, we ensure that by interrupting the profiled thread
     145             :   // (which is the one that owns this list and calls insert() on it) until
     146             :   // we're done reading the list from the signal handler.
     147           0 :   void insert(T* aElement)
     148             :   {
     149           0 :     MOZ_ASSERT(aElement);
     150             : 
     151           0 :     mSignalLock = true;
     152             : 
     153           0 :     mList.insert(aElement);
     154             : 
     155           0 :     mSignalLock = false;
     156           0 :   }
     157             : 
     158             :   // Called within signal, from any thread, possibly while insert() is in the
     159             :   // middle of modifying the list (on the owning thread). Will return null if
     160             :   // that is the case.
     161             :   // Function must be reentrant.
     162           0 :   ProfilerLinkedList<T>* accessList()
     163             :   {
     164           0 :     return mSignalLock ? nullptr : &mList;
     165             :   }
     166             : 
     167             : private:
     168             :   ProfilerLinkedList<T> mList;
     169             : 
     170             :   // If this is set, then it's not safe to read the list because its contents
     171             :   // are being changed.
     172             :   mozilla::Atomic<bool> mSignalLock;
     173             : };
     174             : 
     175             : #endif  // ProfilerMarker_h

Generated by: LCOV version 1.13