Skip to content

Commit

Permalink
Use the same tracked contexts for event pipe and ETW in nativeaot (#8…
Browse files Browse the repository at this point in the history
…9902)

- Make tracking for event pipe and ETW enabled/status use the same contexts
- Switch to using the .NET ETW provider GUIDs instead of .NET Native
- Implement ep_rt_providers_validate_all_disabled (uses the contexts)
  • Loading branch information
elinor-fung authored Aug 4, 2023
1 parent dad076d commit fa78033
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 333 deletions.
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

0 comments on commit fa78033

Please sign in to comment.