1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright 2015 The Chromium Authors. All rights reserved.
2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be
3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file.
4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_FILES_FILE_TRACING_H_
6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_FILES_FILE_TRACING_H_
7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stdint.h>
9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h"
11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/macros.h"
12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define FILE_TRACING_PREFIX "File"
14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define SCOPED_FILE_TRACE_WITH_SIZE(name, size) \
16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    FileTracing::ScopedTrace scoped_file_trace; \
17cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (FileTracing::IsCategoryEnabled()) \
18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      scoped_file_trace.Initialize(FILE_TRACING_PREFIX "::" name, this, size)
19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define SCOPED_FILE_TRACE(name) SCOPED_FILE_TRACE_WITH_SIZE(name, 0)
21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base {
23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass File;
25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass FilePath;
26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BASE_EXPORT FileTracing {
28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public:
29cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  // Whether the file tracing category is enabled.
30cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  static bool IsCategoryEnabled();
31cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  class Provider {
33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat   public:
3496074fa37c50405bb055408ea7753159eb9c3e50Daniel Erat    virtual ~Provider() = default;
3596074fa37c50405bb055408ea7753159eb9c3e50Daniel Erat
36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Whether the file tracing category is currently enabled.
37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    virtual bool FileTracingCategoryIsEnabled() const = 0;
38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Enables file tracing for |id|. Must be called before recording events.
403a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    virtual void FileTracingEnable(const void* id) = 0;
41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Disables file tracing for |id|.
433a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    virtual void FileTracingDisable(const void* id) = 0;
44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Begins an event for |id| with |name|. |path| tells where in the directory
46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // structure the event is happening (and may be blank). |size| is the number
47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // of bytes involved in the event.
48cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    virtual void FileTracingEventBegin(const char* name,
493a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli                                       const void* id,
50cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                                       const FilePath& path,
51cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                                       int64_t size) = 0;
52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Ends an event for |id| with |name|.
543a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    virtual void FileTracingEventEnd(const char* name, const void* id) = 0;
55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  };
56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Sets a global file tracing provider to query categories and record events.
58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static void SetProvider(Provider* provider);
59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Enables file tracing while in scope.
61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  class ScopedEnabler {
62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat   public:
63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ScopedEnabler();
64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ~ScopedEnabler();
65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  };
66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  class ScopedTrace {
68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat   public:
69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ScopedTrace();
70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ~ScopedTrace();
71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Called only if the tracing category is enabled. |name| is the name of the
73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // event to trace (e.g. "Read", "Write") and must have an application
74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // lifetime (e.g. static or literal). |file| is the file being traced; must
75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // outlive this class. |size| is the size (in bytes) of this event.
763a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    void Initialize(const char* name, const File* file, int64_t size);
77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat   private:
79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // The ID of this trace. Based on the |file| passed to |Initialize()|. Must
80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // outlive this class.
813a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    const void* id_;
82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // The name of the event to trace (e.g. "Read", "Write"). Prefixed with
84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // "File".
85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const char* name_;
86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  };
89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  DISALLOW_COPY_AND_ASSIGN(FileTracing);
91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat};
92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace base
94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif  // BASE_FILES_FILE_TRACING_H_
96