Create TraceLogging Framework

Changes based on Design Doc: https://docs.google.com/document/d/1pmZXIULMzDIuQJAQaJg0-rKrJ-eJlTYf7TRZYCBNXmo/edit?usp=sharing
- Create new TraceLogging Framework
- Define Macros for improved perf
- Define interface for platform-specific code
  - Add example interface implementation to be used in standalone mode
- Create UTs for above
- Integrate TraceLogging infra with existing TaskRunner and Informational Logging infras

Change-Id: I728b5742116468c48ffc999144c3d339d2547795
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1612337
Commit-Queue: Ryan Keane <rwkeane@google.com>
Reviewed-by: Yuri Wiitala <miu@chromium.org>
Reviewed-by: Max Yakimakha <yakimakha@chromium.org>
Reviewed-by: mark a. foltz <mfoltz@chromium.org>
diff --git a/platform/impl/task_runner.h b/platform/impl/task_runner.h
index 7de2282..084d628 100644
--- a/platform/impl/task_runner.h
+++ b/platform/impl/task_runner.h
@@ -18,6 +18,7 @@
 #include "absl/types/optional.h"
 #include "platform/api/network_runner.h"
 #include "platform/api/time.h"
+#include "platform/api/trace_logging.h"
 #include "platform/base/error.h"
 
 namespace openscreen {
@@ -74,6 +75,21 @@
   void RunUntilIdleForTesting();
 
  private:
+  // Wrapper around a Task used to store the TraceId Metadata along with the
+  // task itself, and to set the current TraceIdHierarchy before executing the
+  // task.
+  class TaskWithMetadata {
+   public:
+    // NOTE: Conversion constructor required due to condition_variable library.
+    TaskWithMetadata(Task task);
+
+    void operator()();
+
+   private:
+    Task task_;
+    TraceIdHierarchy trace_ids_;
+  };
+
   // Run all tasks already in the task queue. If the queue is empty, wait for
   // either (1) a delayed task to become available, or (2) a task to be added
   // to the queue.
@@ -109,8 +125,9 @@
   // notifying the run loop to wake up when it is waiting for a task to be added
   // to the queue in |run_loop_wakeup_|.
   std::mutex task_mutex_;
-  std::vector<Task> tasks_ GUARDED_BY(task_mutex_);
-  std::multimap<Clock::time_point, Task> delayed_tasks_ GUARDED_BY(task_mutex_);
+  std::vector<TaskWithMetadata> tasks_ GUARDED_BY(task_mutex_);
+  std::multimap<Clock::time_point, TaskWithMetadata> delayed_tasks_
+      GUARDED_BY(task_mutex_);
 
   // When |task_waiter_| is nullptr, |run_loop_wakeup_| is used for sleeping the
   // task runner.  Otherwise, |run_loop_wakeup_| isn't used and |task_waiter_|
@@ -122,7 +139,7 @@
   // To prevent excessive re-allocation of the underlying array of the |tasks_|
   // vector, use an A/B vector-swap mechanism. |running_tasks_| starts out
   // empty, and is swapped with |tasks_| when it is time to run the Tasks.
-  std::vector<Task> running_tasks_;
+  std::vector<TaskWithMetadata> running_tasks_;
 
   OSP_DISALLOW_COPY_AND_ASSIGN(TaskRunnerImpl);
 };