blob: b6bb0a14e6d031ff32f780c9338cd40fc478b72d [file] [log] [blame]
Austin Schuh745610d2015-09-06 18:19:50 -07001// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2/* Copyright (c) 2009, Google Inc.
3 * All rights reserved.
Brian Silverman20350ac2021-11-17 18:19:55 -08004 *
Austin Schuh745610d2015-09-06 18:19:50 -07005 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
Brian Silverman20350ac2021-11-17 18:19:55 -08008 *
Austin Schuh745610d2015-09-06 18:19:50 -07009 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
Brian Silverman20350ac2021-11-17 18:19:55 -080018 *
Austin Schuh745610d2015-09-06 18:19:50 -070019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * ---
32 * Author: Nabeel Mian
33 *
34 * This module manages the cpu profile timers and the associated interrupt
Brian Silverman20350ac2021-11-17 18:19:55 -080035 * handler. When enabled, all threads in the program are profiled.
Austin Schuh745610d2015-09-06 18:19:50 -070036 *
37 * Any component interested in receiving a profile timer interrupt can do so by
38 * registering a callback. All registered callbacks must be async-signal-safe.
39 *
Brian Silverman20350ac2021-11-17 18:19:55 -080040 * Note: This module requires the sole ownership of the configured timer and
41 * signal. The timer defaults to ITIMER_PROF, can be changed to ITIMER_REAL by
42 * the environment variable CPUPROFILE_REALTIME, or is changed to a POSIX timer
43 * with CPUPROFILE_PER_THREAD_TIMERS. The signal defaults to SIGPROF/SIGALRM to
44 * match the choice of timer and can be set to an arbitrary value using
45 * CPUPROFILE_TIMER_SIGNAL with CPUPROFILE_PER_THREAD_TIMERS.
Austin Schuh745610d2015-09-06 18:19:50 -070046 */
47
48#ifndef BASE_PROFILE_HANDLER_H_
49#define BASE_PROFILE_HANDLER_H_
50
51#include "config.h"
52#include <signal.h>
53#ifdef COMPILER_MSVC
54#include "conflict-signal.h"
55#endif
56#include "base/basictypes.h"
57
Austin Schuh745610d2015-09-06 18:19:50 -070058/* Forward declaration. */
59struct ProfileHandlerToken;
60
61/*
62 * Callback function to be used with ProfilefHandlerRegisterCallback. This
63 * function will be called in the context of SIGPROF signal handler and must
64 * be async-signal-safe. The first three arguments are the values provided by
65 * the SIGPROF signal handler. We use void* to avoid using ucontext_t on
66 * non-POSIX systems.
67 *
68 * Requirements:
69 * - Callback must be async-signal-safe.
70 * - None of the functions in ProfileHandler are async-signal-safe. Therefore,
71 * callback function *must* not call any of the ProfileHandler functions.
72 * - Callback is not required to be re-entrant. At most one instance of
73 * callback can run at a time.
74 *
75 * Notes:
76 * - The SIGPROF signal handler saves and restores errno, so the callback
77 * doesn't need to.
78 * - Callback code *must* not acquire lock(s) to serialize access to data shared
79 * with the code outside the signal handler (callback must be
80 * async-signal-safe). If such a serialization is needed, follow the model
81 * used by profiler.cc:
82 *
83 * When code other than the signal handler modifies the shared data it must:
84 * - Acquire lock.
85 * - Unregister the callback with the ProfileHandler.
86 * - Modify shared data.
87 * - Re-register the callback.
88 * - Release lock.
89 * and the callback code gets a lockless, read-write access to the data.
90 */
91typedef void (*ProfileHandlerCallback)(int sig, siginfo_t* sig_info,
92 void* ucontext, void* callback_arg);
93
94/*
95 * Registers a new thread with profile handler and should be called only once
96 * per thread. The main thread is registered at program startup. This routine
97 * is called by the Thread module in google3/thread whenever a new thread is
98 * created. This function is not async-signal-safe.
99 */
100void ProfileHandlerRegisterThread();
101
102/*
103 * Registers a callback routine. This callback function will be called in the
104 * context of SIGPROF handler, so must be async-signal-safe. The returned token
105 * is to be used when unregistering this callback via
106 * ProfileHandlerUnregisterCallback. Registering the first callback enables
107 * the SIGPROF signal handler. Caller must not free the returned token. This
108 * function is not async-signal-safe.
109 */
110ProfileHandlerToken* ProfileHandlerRegisterCallback(
111 ProfileHandlerCallback callback, void* callback_arg);
112
113/*
114 * Unregisters a previously registered callback. Expects the token returned
115 * by the corresponding ProfileHandlerRegisterCallback and asserts that the
116 * passed token is valid. Unregistering the last callback disables the SIGPROF
117 * signal handler. It waits for the currently running callback to
118 * complete before returning. This function is not async-signal-safe.
119 */
120void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token);
121
122/*
123 * FOR TESTING ONLY
124 * Unregisters all the callbacks, stops the timers (if shared) and disables the
125 * SIGPROF handler. All the threads, including the main thread, need to be
126 * re-registered after this call. This function is not async-signal-safe.
127 */
128void ProfileHandlerReset();
129
130/*
131 * Stores profile handler's current state. This function is not
132 * async-signal-safe.
133 */
134struct ProfileHandlerState {
135 int32 frequency; /* Profiling frequency */
136 int32 callback_count; /* Number of callbacks registered */
137 int64 interrupts; /* Number of interrupts received */
138 bool allowed; /* Profiling is allowed */
139};
140void ProfileHandlerGetState(struct ProfileHandlerState* state);
141
Austin Schuh745610d2015-09-06 18:19:50 -0700142#endif /* BASE_PROFILE_HANDLER_H_ */