Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the same tracked contexts for event pipe and ETW in nativeaot #89902

Merged
merged 4 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 91 additions & 101 deletions src/coreclr/nativeaot/Runtime/EtwEvents.h

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/coreclr/nativeaot/Runtime/PalRedhawk.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@

#endif // !_MSC_VER

#ifdef TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '/'
#else // TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '\\'
#endif // TARGET_UNIX

#ifndef _INC_WINDOWS

// There are some fairly primitive type definitions below but don't pull them into the rest of Redhawk unless
Expand All @@ -73,12 +79,6 @@ typedef wchar_t TCHAR;
#define _T(s) L##s
#endif

#ifdef TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '/'
#else // TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '\\'
#endif // TARGET_UNIX

typedef union _LARGE_INTEGER {
struct {
#if BIGENDIAN
Expand Down
131 changes: 1 addition & 130 deletions src/coreclr/nativeaot/Runtime/eventpipe/dotnetruntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <common.h>
#include "eventpipeadapter.h"
#include "eventtrace_context.h"
#include "gcheaputilities.h"

#ifndef ERROR_WRITE_FAULT
Expand Down Expand Up @@ -2935,136 +2936,6 @@ ULONG EventPipeWriteEventGCFitBucketInfo(
return ERROR_SUCCESS;
}

typedef struct _MCGEN_TRACE_CONTEXT
{
TRACEHANDLE RegistrationHandle;
TRACEHANDLE Logger; // Used as pointer to provider traits.
ULONGLONG MatchAnyKeyword;
ULONGLONG MatchAllKeyword;
ULONG Flags;
ULONG IsEnabled;
unsigned char Level;
unsigned char Reserve;
unsigned short EnableBitsCount;
ULONG * EnableBitMask;
const ULONGLONG* EnableKeyWords;
const unsigned char* EnableLevel;
} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT;

#if !defined(EVENTPIPE_TRACE_CONTEXT_DEF)
#define EVENTPIPE_TRACE_CONTEXT_DEF
typedef struct _EVENTPIPE_TRACE_CONTEXT
{
const WCHAR * Name;
unsigned char Level;
bool IsEnabled;
ULONGLONG EnabledKeywordsBitmask;
} EVENTPIPE_TRACE_CONTEXT, *PEVENTPIPE_TRACE_CONTEXT;
#endif // EVENTPIPE_TRACE_CONTEXT_DEF

#if !defined(DOTNET_TRACE_CONTEXT_DEF)
#define DOTNET_TRACE_CONTEXT_DEF
typedef struct _DOTNET_TRACE_CONTEXT
{
PMCGEN_TRACE_CONTEXT EtwProvider;
EVENTPIPE_TRACE_CONTEXT EventPipeProvider;
} DOTNET_TRACE_CONTEXT, *PDOTNET_TRACE_CONTEXT;
#endif // DOTNET_TRACE_CONTEXT_DEF


enum CallbackProviderIndex
{
DotNETRuntime = 0,
DotNETRuntimeRundown = 1,
DotNETRuntimeStress = 2,
DotNETRuntimePrivate = 3
};

void EtwCallbackCommon(
CallbackProviderIndex ProviderIndex,
ULONG ControlCode,
unsigned char Level,
ULONGLONG MatchAnyKeyword,
PVOID pFilterData,
BOOL isEventPipeCallback);

void EventPipeEtwCallbackDotNETRuntime(
_In_ GUID * SourceId,
_In_ ULONG ControlCode,
_In_ unsigned char Level,
_In_ ULONGLONG MatchAnyKeyword,
_In_ ULONGLONG MatchAllKeyword,
_In_opt_ EventFilterDescriptor* FilterData,
_Inout_opt_ PVOID CallbackContext);


void EventPipeEtwCallbackDotNETRuntime(
_In_ GUID * SourceId,
_In_ ULONG ControlCode,
_In_ unsigned char Level,
_In_ ULONGLONG MatchAnyKeyword,
_In_ ULONGLONG MatchAllKeyword,
_In_opt_ EventFilterDescriptor* FilterData,
_Inout_opt_ PVOID CallbackContext)
{
EtwCallbackCommon(DotNETRuntime, ControlCode, Level, MatchAnyKeyword, FilterData, true);
}

DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context;

// @TODO
int const EVENT_CONTROL_CODE_ENABLE_PROVIDER=1;
int const EVENT_CONTROL_CODE_DISABLE_PROVIDER=0;

void EtwCallbackCommon(
CallbackProviderIndex ProviderIndex,
ULONG ControlCode,
unsigned char Level,
ULONGLONG MatchAnyKeyword,
PVOID pFilterData,
BOOL isEventPipeCallback)
{
// LIMITED_METHOD_CONTRACT;

bool bIsPublicTraceHandle = ProviderIndex == DotNETRuntime;

DOTNET_TRACE_CONTEXT * ctxToUpdate;
switch(ProviderIndex)
{
case DotNETRuntime:
ctxToUpdate = &MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context;
break;
default:
_ASSERTE(!"EtwCallbackCommon was called with invalid context");
return;
}

// This callback gets called on both ETW/EventPipe session enable/disable.
// We need toupdate the EventPipe provider context if we are in a callback
// from EventPipe, but not from ETW.
if (isEventPipeCallback)
{
ctxToUpdate->EventPipeProvider.Level = Level;
ctxToUpdate->EventPipeProvider.EnabledKeywordsBitmask = MatchAnyKeyword;
ctxToUpdate->EventPipeProvider.IsEnabled = ControlCode;

// For EventPipe, ControlCode can only be either 0 or 1.
_ASSERTE(ControlCode == 0 || ControlCode == 1);
}

if (
#if !defined(HOST_UNIX)
(ControlCode == EVENT_CONTROL_CODE_ENABLE_PROVIDER || ControlCode == EVENT_CONTROL_CODE_DISABLE_PROVIDER) &&
#endif
(ProviderIndex == DotNETRuntime || ProviderIndex == DotNETRuntimePrivate))
{
GCEventKeyword keywords = static_cast<GCEventKeyword>(ctxToUpdate->EventPipeProvider.EnabledKeywordsBitmask);
GCEventLevel level = static_cast<GCEventLevel>(ctxToUpdate->EventPipeProvider.Level);
GCHeapUtilities::RecordEventStateChange(bIsPublicTraceHandle, keywords, level);
}
}


void InitProvidersAndEvents(void)
{
InitDotNETRuntime();
Expand Down
49 changes: 16 additions & 33 deletions src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@
#include "thread.h"
#include "threadstore.h"
#include "threadstore.inl"

#ifndef DIRECTORY_SEPARATOR_CHAR
#ifdef TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '/'
#else // TARGET_UNIX
#define DIRECTORY_SEPARATOR_CHAR '\\'
#endif // TARGET_UNIX
#endif
#include "eventtrace_context.h"

// Uses _rt_aot_lock_internal_t that has CrstStatic as a field
// This is initialized at the beginning and EventPipe library requires the lock handle to be maintained by the runtime
Expand All @@ -47,13 +40,6 @@ uint32_t *_ep_rt_aot_proc_group_offsets;
*/


static
void
walk_managed_stack_for_threads (
ep_rt_thread_handle_t sampling_thread,
EventPipeEvent *sampling_event);


bool
ep_rt_aot_walk_managed_stack_for_thread (
ep_rt_thread_handle_t thread,
Expand All @@ -63,14 +49,11 @@ ep_rt_aot_walk_managed_stack_for_thread (
return false;
}

// The thread store lock must already be held by the thread before this function
// is called. ThreadSuspend::SuspendEE acquires the thread store lock.
static
void
walk_managed_stack_for_threads (
ep_rt_thread_handle_t sampling_thread,
EventPipeEvent *sampling_event)
bool
ep_rt_aot_providers_validate_all_disabled (void)
{
return !MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled
&& !MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled;
}

void
Expand All @@ -81,7 +64,7 @@ ep_rt_aot_sample_profiler_write_sampling_event_for_threads (
}

const ep_char8_t *
ep_rt_aot_entrypoint_assembly_name_get_utf8 (void)
ep_rt_aot_entrypoint_assembly_name_get_utf8 (void)
{
// We are (intentionally for now) using the module name rather than entry assembly
// Cannot use __cpp_threadsafe_static_init feature since it will bring in the C++ runtime and need to use threadsafe way to initialize entrypoint_assembly_name
Expand Down Expand Up @@ -252,7 +235,7 @@ ep_rt_aot_atomic_inc_int64_t (volatile int64_t *value)
}

int64_t
ep_rt_aot_atomic_dec_int64_t (volatile int64_t *value) {
ep_rt_aot_atomic_dec_int64_t (volatile int64_t *value) {
STATIC_CONTRACT_NOTHROW;

int64_t currentValue;
Expand All @@ -275,7 +258,7 @@ ep_rt_aot_atomic_compare_exchange_size_t (volatile size_t *target, size_t expect
}

ep_char8_t *
ep_rt_aot_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) {
ep_rt_aot_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) {
STATIC_CONTRACT_NOTHROW;
return static_cast<ep_char8_t *>(PalInterlockedCompareExchangePointer ((void *volatile *)target, value, expected));
}
Expand Down Expand Up @@ -315,8 +298,8 @@ ep_rt_aot_wait_event_free (ep_rt_wait_event_handle_t *wait_event)
}

bool
ep_rt_aot_wait_event_set (ep_rt_wait_event_handle_t *wait_event)
{
ep_rt_aot_wait_event_set (ep_rt_wait_event_handle_t *wait_event)
{
STATIC_CONTRACT_NOTHROW;
EP_ASSERT (wait_event != NULL && wait_event->event != NULL);

Expand All @@ -327,17 +310,17 @@ int32_t
ep_rt_aot_wait_event_wait (
ep_rt_wait_event_handle_t *wait_event,
uint32_t timeout,
bool alertable)
{
bool alertable)
{
STATIC_CONTRACT_NOTHROW;
EP_ASSERT (wait_event != NULL && wait_event->event != NULL);

return wait_event->event->Wait (timeout, alertable);
}

bool
ep_rt_aot_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event)
{
ep_rt_aot_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event)
{
STATIC_CONTRACT_NOTHROW;

if (wait_event == NULL || wait_event->event == NULL)
Expand Down Expand Up @@ -731,7 +714,7 @@ bool ep_rt_aot_lock_release (ep_rt_lock_handle_t *lock)

bool ep_rt_aot_spin_lock_acquire (ep_rt_spin_lock_handle_t *spin_lock)
{
// In NativeAOT, we use a lock, instead of a SpinLock.
// In NativeAOT, we use a lock, instead of a SpinLock.
// The method signature matches the EventPipe library expectation of a SpinLock
if (spin_lock) {
spin_lock->lock->Enter();
Expand All @@ -742,7 +725,7 @@ bool ep_rt_aot_spin_lock_acquire (ep_rt_spin_lock_handle_t *spin_lock)

bool ep_rt_aot_spin_lock_release (ep_rt_spin_lock_handle_t *spin_lock)
{
// In NativeAOT, we use a lock, instead of a SpinLock.
// In NativeAOT, we use a lock, instead of a SpinLock.
// The method signature matches the EventPipe library expectation of a SpinLock
if (spin_lock) {
spin_lock->lock->Leave();
Expand Down
Loading
Loading