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/. */
6 
7 #ifndef TRACED_TASK_COMMON_H
8 #define TRACED_TASK_COMMON_H
9 
10 #include "GeckoTaskTracer.h"
11 
12 #include "nsCOMPtr.h"
13 #include "nsThreadUtils.h"
14 
15 namespace mozilla {
16 namespace tasktracer {
17 
18 class TracedTaskCommon {
19  public:
20   TracedTaskCommon();
TracedTaskCommon(const TracedTaskCommon & aSrc)21   TracedTaskCommon(const TracedTaskCommon& aSrc)
22       : mSourceEventType(aSrc.mSourceEventType),
23         mSourceEventId(aSrc.mSourceEventId),
24         mParentTaskId(aSrc.mParentTaskId),
25         mTaskId(aSrc.mTaskId),
26         mIsTraceInfoInit(aSrc.mIsTraceInfoInit) {}
27   virtual ~TracedTaskCommon();
28 
29   void DispatchTask(int aDelayTimeMs = 0);
30 
SetTLSTraceInfo()31   void SetTLSTraceInfo() {
32     if (mIsTraceInfoInit) {
33       DoSetTLSTraceInfo();
34     }
35   }
GetTLSTraceInfo()36   void GetTLSTraceInfo() {
37     if (IsStartLogging()) {
38       DoGetTLSTraceInfo();
39     }
40   }
41   void ClearTLSTraceInfo();
42 
43  private:
44   void DoSetTLSTraceInfo();
45   void DoGetTLSTraceInfo();
46 
47  protected:
48   void Init();
49 
50   // TraceInfo of TLS will be set by the following parameters, including source
51   // event type, source event ID, parent task ID, and task ID of this traced
52   // task/runnable.
53   SourceEventType mSourceEventType;
54   uint64_t mSourceEventId;
55   uint64_t mParentTaskId;
56   uint64_t mTaskId;
57   bool mIsTraceInfoInit;
58 };
59 
60 class TracedRunnable : public TracedTaskCommon, public nsIRunnable {
61  public:
62   NS_DECL_THREADSAFE_ISUPPORTS
63   NS_DECL_NSIRUNNABLE
64 
65   explicit TracedRunnable(already_AddRefed<nsIRunnable>&& aOriginalObj);
66 
67  private:
68   virtual ~TracedRunnable();
69 
70   nsCOMPtr<nsIRunnable> mOriginalObj;
71 };
72 
73 /**
74  * This class is used to create a logical task, without a real
75  * runnable.
76  */
77 class VirtualTask : public TracedTaskCommon {
78  public:
VirtualTask()79   VirtualTask() : TracedTaskCommon() {}
80 
VirtualTask(const VirtualTask & aSrc)81   VirtualTask(const VirtualTask& aSrc) : TracedTaskCommon(aSrc) {}
82 
83   /**
84    * Initialize the task to create an unique ID, and store other
85    * information.
86    *
87    * This method may be called for one or more times.
88    */
89   void Init(uintptr_t* aVPtr = nullptr) {
90     TracedTaskCommon::Init();
91     if (aVPtr) {
92       extern void LogVirtualTablePtr(uint64_t aTaskId, uint64_t aSourceEventId,
93                                      uintptr_t * aVptr);
94       LogVirtualTablePtr(mTaskId, mSourceEventId, aVPtr);
95     }
96     DispatchTask();
97   }
98 
99   /**
100    * Define the life-span of a VirtualTask.
101    *
102    * VirtualTask is not a real task, goes without a runnable, it's
103    * instances are never dispatched and ran by event loops.  This
104    * class used to define running time as the life-span of it's
105    * instance.
106    */
107   class AutoRunTask : public AutoSaveCurTraceInfo {
108     VirtualTask* mTask;
109     void StartScope(VirtualTask* aTask);
110     void StopScope();
111 
112    public:
AutoRunTask(VirtualTask * aTask)113     explicit AutoRunTask(VirtualTask* aTask)
114         : AutoSaveCurTraceInfo(), mTask(aTask) {
115       if (HasSavedTraceInfo()) {
116         StartScope(aTask);
117       }
118     }
~AutoRunTask()119     ~AutoRunTask() {
120       if (HasSavedTraceInfo()) {
121         StopScope();
122       }
123     }
124   };
125 };
126 
127 }  // namespace tasktracer
128 }  // namespace mozilla
129 
130 #endif
131