mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 08:35:26 +00:00
108 lines
4.4 KiB
C
108 lines
4.4 KiB
C
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef MOZ_UNWINDER_THREAD_2_H
|
|
#define MOZ_UNWINDER_THREAD_2_H
|
|
|
|
#include "GeckoProfilerImpl.h"
|
|
#include "ProfileEntry.h"
|
|
|
|
#include "PlatformMacros.h"
|
|
#if defined(SPS_OS_android) || defined(SPS_OS_linux)
|
|
# include "LulMain.h"
|
|
#endif
|
|
|
|
/* Top level exports of UnwinderThread.cpp. */
|
|
|
|
// Abstract type. A buffer which is used to transfer information between
|
|
// the sampled thread(s) and the unwinder thread(s).
|
|
typedef
|
|
struct _UnwinderThreadBuffer
|
|
UnwinderThreadBuffer;
|
|
|
|
// RUNS IN SIGHANDLER CONTEXT
|
|
// Called in the sampled thread (signal) context. Adds a ProfileEntry
|
|
// into an UnwinderThreadBuffer that the thread has previously obtained
|
|
// by a call to utb__acquire_empty_buffer.
|
|
void utb__addEntry(/*MOD*/UnwinderThreadBuffer* utb,
|
|
ProfileEntry ent);
|
|
|
|
// Create the unwinder thread. At the moment there can be only one.
|
|
void uwt__init();
|
|
|
|
// Request the unwinder thread to exit, and wait until it has done so.
|
|
// This must be called before stopping the profiler because we hold a
|
|
// reference to the profile which is owned by the profiler.
|
|
void uwt__stop();
|
|
|
|
// Release the unwinder resources. This must be called after profiling
|
|
// has stop. At this point we know the profiler doesn't hold any buffer
|
|
// and can safely release any resources.
|
|
void uwt__deinit();
|
|
|
|
// Registers a sampler thread for profiling. Threads must be
|
|
// registered before calls to call utb__acquire_empty_buffer or
|
|
// utb__release_full_buffer have any effect. If stackTop is
|
|
// nullptr, the call is ignored.
|
|
void uwt__register_thread_for_profiling(void* stackTop);
|
|
|
|
// Deregister a sampler thread for profiling.
|
|
void uwt__unregister_thread_for_profiling();
|
|
|
|
// RUNS IN SIGHANDLER CONTEXT
|
|
// Called in the sampled thread (signal) context. Get an empty buffer
|
|
// into which ProfileEntries can be put. It may return nullptr if no
|
|
// empty buffers can be found, which will be the case if the unwinder
|
|
// thread(s) have fallen behind for some reason. In this case the
|
|
// sampled thread must simply give up and return from the signal
|
|
// handler immediately, else it risks deadlock.
|
|
//
|
|
// If the calling thread has not previously registered itself for
|
|
// profiling via uwt__register_thread_for_profiling, this routine
|
|
// returns nullptr.
|
|
UnwinderThreadBuffer* uwt__acquire_empty_buffer();
|
|
|
|
// RUNS IN SIGHANDLER CONTEXT
|
|
// Called in the sampled thread (signal) context. Release a buffer
|
|
// that the sampled thread has acquired, handing the contents to
|
|
// the unwinder thread, and, if necessary, passing sufficient
|
|
// information (stack top chunk, + registers) to also do a native
|
|
// unwind. If 'ucV' is nullptr, no native unwind is done. If non-nullptr,
|
|
// it is assumed to point to a ucontext_t* that holds the initial
|
|
// register state for the unwind. The results of all of this are
|
|
// dumped into |aProfile| (by the unwinder thread, not the calling thread).
|
|
void uwt__release_full_buffer(ThreadProfile* aProfile,
|
|
UnwinderThreadBuffer* utb,
|
|
void* /* ucontext_t*, really */ ucV);
|
|
|
|
struct LinkedUWTBuffer;
|
|
|
|
// Get an empty buffer for synchronous unwinding.
|
|
// This function is NOT signal-safe.
|
|
LinkedUWTBuffer* utb__acquire_sync_buffer(void* stackTop);
|
|
|
|
void utb__finish_sync_buffer(ThreadProfile* aProfile,
|
|
UnwinderThreadBuffer* utb,
|
|
void* /* ucontext_t*, really */ ucV);
|
|
|
|
// Free an empty buffer that was previously allocated by
|
|
// utb__acquire_sync_buffer.
|
|
void utb__release_sync_buffer(LinkedUWTBuffer* utb);
|
|
|
|
// Unwind complete, mark a synchronous unwind buffer as empty
|
|
void utb__end_sync_buffer_unwind(LinkedUWTBuffer* utb);
|
|
|
|
// This typedef must match uwt__release_full_buffer and uwt__finish_sync_buffer
|
|
typedef void (*UTB_RELEASE_FUNC)(ThreadProfile*,UnwinderThreadBuffer*,void*);
|
|
|
|
#if defined(SPS_OS_android) || defined(SPS_OS_linux)
|
|
// Notify |aLUL| of the objects in the current process, so as to get
|
|
// it to read unwind data for them. This has to be externally visible
|
|
// so it can be used in LUL unit tests, tools/profiler/tests/gtest/LulTest.cpp.
|
|
void read_procmaps(lul::LUL* aLUL);
|
|
#endif
|
|
|
|
#endif /* ndef MOZ_UNWINDER_THREAD_2_H */
|