<IlcRPath Condition="'$(IlcRPath)' == '' and '$(_IsApplePlatform)' == 'true'">@executable_path</IlcRPath>
<EventPipeName>libeventpipe-disabled</EventPipeName>
- <EventPipeName Condition="'$(EnableNativeEventPipe)' == 'true'">libeventpipe-enabled</EventPipeName>
+ <EventPipeName Condition="'$(EnableNativeEventPipe)' == 'true' or ('$(EventSourceSupport)' == 'true' and '$(_IsApplePlatform)' != 'true')">libeventpipe-enabled</EventPipeName>
</PropertyGroup>
<ItemGroup>
</PropertyGroup>
<PropertyGroup>
<FeaturePerfTracing>false</FeaturePerfTracing>
- <FeaturePerfTracing Condition="'$(TargetsWindows)' == 'true'">true</FeaturePerfTracing>
+ <FeaturePerfTracing Condition="'$(TargetsWindows)' == 'true' or ('$(TargetsUnix)' == 'true' and '$(TargetsOSX)' != 'true' and '$(TargetsiOS)' != 'true' and '$(TargetsMacCatalyst)' != 'true' and '$(TargetstvOS)' != 'true')">true</FeaturePerfTracing>
</PropertyGroup>
<PropertyGroup>
<DefineConstants Condition="'$(FeaturePerfTracing)' == 'true'">FEATURE_PERFTRACING;$(DefineConstants)</DefineConstants>
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalAttachThread(void* thread);
REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalDetachThread(void* thread);
-REDHAWK_PALIMPORT uint64_t PalGetCurrentThreadIdForLogging();
+REDHAWK_PALIMPORT uint64_t PalGetCurrentOSThreadId();
REDHAWK_PALIMPORT uint64_t PalQueryPerformanceCounter();
REDHAWK_PALIMPORT uint64_t PalQueryPerformanceFrequency();
include (${SHARED_EVENTPIPE_SOURCE_PATH}/eventpipe.cmake)
include (${SHARED_CONTAINERS_SOURCE_PATH}/containers.cmake)
-list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES
- ds-ipc-pal-namedpipe.c
-)
+if(CLR_CMAKE_HOST_WIN32)
+ list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES
+ ds-ipc-pal-namedpipe.c
+ )
-list(APPEND SHARED_DIAGNOSTIC_SERVER_HEADERS
- ds-ipc-pal-namedpipe.h
-)
+ list(APPEND SHARED_DIAGNOSTIC_SERVER_HEADERS
+ ds-ipc-pal-namedpipe.h
+ )
+endif(CLR_CMAKE_HOST_WIN32)
+
+if(CLR_CMAKE_HOST_UNIX)
+ list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES
+ ds-ipc-pal-socket.c
+ )
+
+ list(APPEND SHARED_DIAGNOSTIC_SERVER_HEADERS
+ ds-ipc-pal-socket.h
+ )
+endif(CLR_CMAKE_HOST_UNIX)
list(APPEND EVENTPIPE_SOURCES
${SHARED_EVENTPIPE_SOURCES}
list(APPEND AOT_EVENTPIPE_SHIM_SOURCES
${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.cpp
+ ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-aot.cpp
)
list(APPEND AOT_EVENTPIPE_SHIM_HEADERS
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include <eventpipe/ep-rt-config.h>
+
+#ifdef ENABLE_PERFTRACING
+#include <eventpipe/ep-types.h>
+#include <eventpipe/ep.h>
+#include <eventpipe/ep-stack-contents.h>
+#include <eventpipe/ep-rt.h>
+
+#include "ds-rt-aot.h"
+
+bool aot_ipc_get_process_id_disambiguation_key(uint32_t process_id, uint64_t *key);
+
+bool
+aot_ipc_get_process_id_disambiguation_key(
+ uint32_t process_id,
+ uint64_t *key)
+{
+ if (!key) {
+ EP_ASSERT (!"key argument cannot be null!");
+ return false;
+ }
+
+ *key = 0;
+
+// Mono implementation, restricted just to Unix
+#ifdef TARGET_UNIX
+
+ // Here we read /proc/<pid>/stat file to get the start time for the process.
+ // We return this value (which is expressed in jiffies since boot time).
+
+ // Making something like: /proc/123/stat
+ char stat_file_name [64];
+ snprintf (stat_file_name, sizeof (stat_file_name), "/proc/%d/stat", process_id);
+
+ FILE *stat_file = fopen (stat_file_name, "r");
+ if (!stat_file) {
+ EP_ASSERT (!"Failed to get start time of a process, fopen failed.");
+ return false;
+ }
+
+ bool result = false;
+ unsigned long long start_time = 0;
+ char *scan_start_position;
+ int result_sscanf;
+
+ char *line = NULL;
+ size_t line_len = 0;
+ if (getline (&line, &line_len, stat_file) == -1)
+ {
+ EP_ASSERT (!"Failed to get start time of a process, getline failed.");
+ ep_raise_error ();
+ }
+
+
+ // According to `man proc`, the second field in the stat file is the filename of the executable,
+ // in parentheses. Tokenizing the stat file using spaces as separators breaks when that name
+ // has spaces in it, so we start using sscanf_s after skipping everything up to and including the
+ // last closing paren and the space after it.
+ scan_start_position = strrchr (line, ')');
+ if (!scan_start_position || scan_start_position [1] == '\0') {
+ EP_ASSERT (!"Failed to parse stat file contents with strrchr.");
+ ep_raise_error ();
+ }
+
+ scan_start_position += 2;
+
+ // All the format specifiers for the fields in the stat file are provided by 'man proc'.
+ result_sscanf = sscanf (scan_start_position,
+ "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %llu \n",
+ &start_time);
+
+ if (result_sscanf != 1) {
+ EP_ASSERT (!"Failed to parse stat file contents with sscanf.");
+ ep_raise_error ();
+ }
+
+ free (line);
+ fclose (stat_file);
+ result = true;
+
+ep_on_exit:
+ *key = (uint64_t)start_time;
+ return result;
+
+ep_on_error:
+ free (line);
+ fclose (stat_file);
+ result = false;
+ ep_exit_error_handler ();
+
+#else
+ // If we don't have /proc, we just return false.
+ DS_LOG_WARNING_0 ("ipc_get_process_id_disambiguation_key was called but is not implemented on this platform!");
+ return false;
+#endif
+}
+
+bool
+ds_rt_aot_transport_get_default_name (
+ ep_char8_t *name,
+ int32_t name_len,
+ const ep_char8_t *prefix,
+ int32_t id,
+ const ep_char8_t *group_id,
+ const ep_char8_t *suffix)
+{
+ STATIC_CONTRACT_NOTHROW;
+
+#ifdef TARGET_UNIX
+
+ EP_ASSERT (name != NULL);
+
+ bool result = false;
+ int32_t format_result = 0;
+ uint64_t disambiguation_key = 0;
+ ep_char8_t *format_buffer = NULL;
+
+ *name = '\0';
+
+ format_buffer = (ep_char8_t *)malloc (name_len + 1);
+ ep_raise_error_if_nok (format_buffer != NULL);
+
+ *format_buffer = '\0';
+
+ // If ipc_get_process_id_disambiguation_key failed for some reason, it should set the value
+ // to 0. We expect that anyone else making the pipe name will also fail and thus will
+ // also try to use 0 as the value.
+ if (!aot_ipc_get_process_id_disambiguation_key (id, &disambiguation_key))
+ EP_ASSERT (disambiguation_key == 0);
+
+ // Get a temp file location
+ format_result = ep_rt_temp_path_get (format_buffer, name_len);
+ if (format_result == 0) {
+ DS_LOG_ERROR_0 ("ep_rt_temp_path_get failed");
+ ep_raise_error ();
+ }
+
+ EP_ASSERT (format_result <= name_len);
+
+ format_result = snprintf(name, name_len, "%s%s-%d-%llu-%s", format_buffer, prefix, id, (unsigned long long)disambiguation_key, suffix);
+ if (format_result <= 0 || format_result > name_len) {
+ DS_LOG_ERROR_0 ("name buffer too small");
+ ep_raise_error ();
+ }
+
+ result = true;
+
+ep_on_exit:
+ free (format_buffer);
+ return result;
+
+ep_on_error:
+ EP_ASSERT (!result);
+ name [0] = '\0';
+ ep_exit_error_handler ();
+
+#else
+ return true;
+#endif
+}
+#endif /* ENABLE_PERFTRACING */
const ep_char8_t *group_id,
const ep_char8_t *suffix)
{
- STATIC_CONTRACT_NOTHROW;
-
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: PAL_GetTransportName is defined in coreclr\pal\inc\pal.h
- return true;
+
+ extern bool ds_rt_aot_transport_get_default_name (ep_char8_t *name, int32_t name_len, const ep_char8_t *prefix, int32_t id, const ep_char8_t *group_id, const ep_char8_t *suffix);
+
+ return ds_rt_aot_transport_get_default_name(name, name_len, prefix, id, group_id, suffix);
}
/*
#include "holder.h"
#include "SpinLock.h"
+#ifdef TARGET_UNIX
+// Per module (1 for NativeAOT), key that will be used to implement TLS in Unix
+pthread_key_t eventpipe_tls_key;
+__thread EventPipeThreadHolder* eventpipe_tls_instance;
+#else
+thread_local EventPipeAotThreadHolderTLS EventPipeAotThreadHolderTLS::g_threadHolderTLS;
+#endif
+
// 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
ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle;
CrstStatic _ep_rt_aot_config_lock;
-thread_local EventPipeAotThreadHolderTLS EventPipeAotThreadHolderTLS::g_threadHolderTLS;
-
ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line;
#ifndef TARGET_UNIX
STATIC_CONTRACT_NOTHROW;
#ifdef TARGET_UNIX
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: AOT doesn't have PAL_GetCurrentOSThreadId, as CoreCLR does.
- // PalDebugBreak();
- return static_cast<ep_rt_thread_id_t>(0);
+ return static_cast<ep_rt_thread_id_t>(PalGetCurrentOSThreadId());
#else
return static_cast<ep_rt_thread_id_t>(::GetCurrentThreadId ());
#endif
STATIC_CONTRACT_NOTHROW;
EP_ASSERT (str != NULL);
- return wcslen (reinterpret_cast<LPCWSTR>(str));
+ #ifdef TARGET_UNIX
+ const uint16_t *a = (const uint16_t *)str;
+ size_t length = 0;
+ while (a [length])
+ ++length;
+ return length;
+ #else
+ return wcslen (reinterpret_cast<LPCWSTR>(str));
+ #endif
}
uint32_t
VolatileStoreWithoutBarrier<void *> ((void **)ptr, value);
}
+void unix_tls_callback_fn(void *value)
+{
+ if (value) {
+ // we need to do the unallocation here
+ EventPipeThreadHolder *thread_holder_old = static_cast<EventPipeThreadHolder*>(value);
+ // @TODO - inline
+ thread_holder_free_func (thread_holder_old);
+ value = NULL;
+ }
+}
+
void ep_rt_aot_init (void)
{
extern ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle;
_ep_rt_aot_config_lock_handle.lock = &_ep_rt_aot_config_lock;
_ep_rt_aot_config_lock_handle.lock->InitNoThrow (CrstType::CrstEventPipeConfig);
+
+ // Initialize the pthread key used for TLS in Unix
+ #ifdef TARGET_UNIX
+ pthread_key_create(&eventpipe_tls_key, unix_tls_callback_fn);
+ #endif
}
bool ep_rt_aot_lock_acquire (ep_rt_lock_handle_t *lock)
#define __EVENTPIPE_RT_AOT_H__
#include <ctype.h> // For isspace
+#ifdef TARGET_UNIX
+#include <sys/time.h>
+#include <pthread.h>
+#endif
#include <eventpipe/ep-rt-config.h>
#ifdef ENABLE_PERFTRACING
#undef EP_ALIGN_UP
#define EP_ALIGN_UP(val,align) _rt_aot_align_up(val,align)
+#ifdef TARGET_UNIX
+extern pthread_key_t eventpipe_tls_key;
+extern __thread EventPipeThreadHolder* eventpipe_tls_instance;
+#endif
+
// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
// TODO: The NativeAOT ALIGN_UP is defined in a tangled manner that generates linker errors if
// it is used here; instead, define a version tailored to the existing usage in the shared
ep_rt_aot_config_lock_get (void)
{
extern ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle;
- return &_ep_rt_aot_config_lock_handle;
+ return &_ep_rt_aot_config_lock_handle;
}
static
// (CLRConfig::INTERNAL_EventPipeConfig)
// PalDebugBreak();
return nullptr;
-// return ep_rt_utf16_to_utf8_string (reinterpret_cast<ep_char16_t *>(value.GetValue ()), -1);
+// return ep_rt_utf16_to_utf8_string (reinterpret_cast<ep_char16_t *>(value.GetValue ()), -1);
}
static
uint8_t data1[] = {0x67,0xac,0x33,0xf1,0x8d,0xed,0x41,0x01,0xb4,0x26,0xc9,0xb7,0x94,0x35,0xf7,0x8a};
memcpy (activity_id, data1, EP_ACTIVITY_ID_SIZE);
- const uint16_t version_mask = 0xF000;
- const uint16_t random_guid_version = 0x4000;
- const uint8_t clock_seq_hi_and_reserved_mask = 0xC0;
- const uint8_t clock_seq_hi_and_reserved_value = 0x80;
+ const uint16_t version_mask = 0xF000;
+ const uint16_t random_guid_version = 0x4000;
+ const uint8_t clock_seq_hi_and_reserved_mask = 0xC0;
+ const uint8_t clock_seq_hi_and_reserved_value = 0x80;
- // Modify bits indicating the type of the GUID
- uint8_t *activity_id_c = activity_id + sizeof (uint32_t) + sizeof (uint16_t);
- uint8_t *activity_id_d = activity_id + sizeof (uint32_t) + sizeof (uint16_t) + sizeof (uint16_t);
+ // Modify bits indicating the type of the GUID
+ uint8_t *activity_id_c = activity_id + sizeof (uint32_t) + sizeof (uint16_t);
+ uint8_t *activity_id_d = activity_id + sizeof (uint32_t) + sizeof (uint16_t) + sizeof (uint16_t);
- uint16_t c;
- memcpy (&c, activity_id_c, sizeof (c));
+ uint16_t c;
+ memcpy (&c, activity_id_c, sizeof (c));
- uint8_t d;
- memcpy (&d, activity_id_d, sizeof (d));
+ uint8_t d;
+ memcpy (&d, activity_id_d, sizeof (d));
- // time_hi_and_version
- c = ((c & ~version_mask) | random_guid_version);
- // clock_seq_hi_and_reserved
- d = ((d & ~clock_seq_hi_and_reserved_mask) | clock_seq_hi_and_reserved_value);
+ // time_hi_and_version
+ c = ((c & ~version_mask) | random_guid_version);
+ // clock_seq_hi_and_reserved
+ d = ((d & ~clock_seq_hi_and_reserved_mask) | clock_seq_hi_and_reserved_value);
- memcpy (activity_id_c, &c, sizeof (c));
- memcpy (activity_id_d, &d, sizeof (d));
+ memcpy (activity_id_c, &c, sizeof (c));
+ memcpy (activity_id_d, &d, sizeof (d));
}
static
EP_ASSERT(system_time != NULL);
ep_system_time_set (
- system_time,
- value.wYear,
- value.wMonth,
- value.wDayOfWeek,
- value.wDay,
- value.wHour,
- value.wMinute,
- value.wSecond,
- value.wMilliseconds);
-#else
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: Get System time
- // PalDebugBreak();
+ system_time,
+ value.wYear,
+ value.wMonth,
+ value.wDayOfWeek,
+ value.wDay,
+ value.wHour,
+ value.wMinute,
+ value.wSecond,
+ value.wMilliseconds);
+#elif TARGET_UNIX
+ time_t tt;
+ struct tm *ut_ptr;
+ struct timeval time_val;
+ int timeofday_retval;
+
+ EP_ASSERT (system_time != NULL);
+
+ tt = time (NULL);
+
+ timeofday_retval = gettimeofday (&time_val, NULL);
+
+ ut_ptr = gmtime (&tt);
+
+ uint16_t milliseconds = 0;
+ if (timeofday_retval != -1) {
+ int old_seconds;
+ int new_seconds;
+
+ milliseconds = (uint16_t)(time_val.tv_usec / 1000);
+
+ old_seconds = ut_ptr->tm_sec;
+ new_seconds = time_val.tv_sec % 60;
+
+ /* just in case we reached the next second in the interval between time () and gettimeofday () */
+ if (old_seconds != new_seconds)
+ milliseconds = 999;
+ }
+
+ ep_system_time_set (
+ system_time,
+ (uint16_t)(1900 + ut_ptr->tm_year),
+ (uint16_t)ut_ptr->tm_mon + 1,
+ (uint16_t)ut_ptr->tm_wday,
+ (uint16_t)ut_ptr->tm_mday,
+ (uint16_t)ut_ptr->tm_hour,
+ (uint16_t)ut_ptr->tm_min,
+ (uint16_t)ut_ptr->tm_sec,
+ milliseconds);
#endif
}
uint32_t buffer_len)
{
STATIC_CONTRACT_NOTHROW;
-// EP_UNREACHABLE ("Can not reach here");
+#ifdef TARGET_UNIX
+
+ EP_ASSERT (buffer != NULL);
+ EP_ASSERT (buffer_len > 0);
+
+ const ep_char8_t *path = getenv ("TMPDIR");
+ if (path == NULL){
+ path = getenv ("TMP");
+ if (path == NULL){
+ path = getenv ("TEMP");
+ if (path == NULL)
+ path = "/tmp/";
+ }
+ }
+
+ int32_t result = snprintf (buffer, buffer_len, path[strlen(path) - 1] == '/' ? "%s" : "%s/", path);
+ if (result <= 0 || (uint32_t)result >= buffer_len)
+ ep_raise_error ();
+
+
+ep_on_exit:
+ return result;
+
+ep_on_error:
+ result = 0;
+ ep_exit_error_handler ();
+
+#else
return 0;
+#endif
}
static
if (!str)
return NULL;
- // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: Implementation would just use strlen and malloc to make a new buffer, and would then copy the string chars one by one
+ // Shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
+ // Implementation would just use strlen and malloc to make a new buffer, and would then copy the string chars one by one.
+ // Assumes that only ASCII is used for ep_char8_t
size_t len_utf8 = strlen(str);
if (len_utf8 == 0)
return NULL;
for (size_t i = 0; i < len_utf8; i++)
{
+ EP_ASSERT(isascii(str[i]));
str_utf16[i] = str[i];
}
return NULL;
// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase
- // TODO: Temp implementation that is the reverse of ep_rt_utf8_to_utf16le_string
+ // Simple implementation to create a utf8 string from a utf16 one
size_t len_utf16 = len;
if(len_utf16 == (size_t)-1)
- {
len_utf16 = ep_rt_utf16_string_len (str);
- }
ep_char8_t *str_utf8 = reinterpret_cast<ep_char8_t *>(malloc ((len_utf16 + 1) * sizeof (ep_char8_t)));
if (!str_utf8)
// EP_ASSERT (thread_handle != NULL);
}
+#ifdef TARGET_UNIX
+static
+inline
+EventPipeThreadHolder *
+pthread_getThreadHolder (void)
+{
+ void *value = eventpipe_tls_instance;
+ if (value) {
+ EventPipeThreadHolder *thread_holder = static_cast<EventPipeThreadHolder*>(value);
+ return thread_holder;
+ }
+ return NULL;
+}
+
+static
+inline
+EventPipeThreadHolder *
+pthread_createThreadHolder (void)
+{
+ void *value = eventpipe_tls_instance;
+ if (value) {
+ // we need to do the unallocation here
+ EventPipeThreadHolder *thread_holder_old = static_cast<EventPipeThreadHolder*>(value);
+ thread_holder_free_func(thread_holder_old);
+ eventpipe_tls_instance = NULL;
+
+ value = NULL;
+ }
+ EventPipeThreadHolder *instance = thread_holder_alloc_func();
+ if (instance){
+ // We need to know when the thread is no longer in use to clean up EventPipeThreadHolder instance and will use pthread destructor function to get notification when that happens.
+ pthread_setspecific(eventpipe_tls_key, instance);
+ eventpipe_tls_instance = instance;
+ }
+ return instance;
+}
+#endif
+
static
inline
EventPipeThread *
{
STATIC_CONTRACT_NOTHROW;
+#ifdef TARGET_UNIX
+ EventPipeThreadHolder *thread_holder = pthread_getThreadHolder ();
+#else
EventPipeThreadHolder *thread_holder = EventPipeAotThreadHolderTLS::getThreadHolder ();
+#endif
return thread_holder ? ep_thread_holder_get_thread (thread_holder) : NULL;
}
{
STATIC_CONTRACT_NOTHROW;
- EventPipeThreadHolder *thread_holder = EventPipeAotThreadHolderTLS::getThreadHolder ();
+#ifdef TARGET_UNIX
+ EventPipeThreadHolder *thread_holder = pthread_getThreadHolder ();
+ if (!thread_holder)
+ thread_holder = pthread_createThreadHolder ();
+#else
+ EventPipeThreadHolder *thread_holder = EventPipeAotThreadHolderTLS::getThreadHolder ();
if (!thread_holder)
thread_holder = EventPipeAotThreadHolderTLS::createThreadHolder ();
+#endif
return ep_thread_holder_get_thread (thread_holder);
}
// the process is terminated via `exit()` or a signal. Thus there is no such distinction
// between threads.
Thread* g_threadPerformingShutdown = NULL;
+#endif
static void __cdecl OnProcessExit()
{
+#ifdef _WIN32
// The process is exiting and the current thread is performing the shutdown.
// When this thread exits some threads may be already rudely terminated.
// It would not be a good idea for this thread to wait on any locks
// or run managed code at shutdown, so we will not try detaching it.
Thread* currentThread = ThreadStore::RawGetCurrentThread();
g_threadPerformingShutdown = currentThread;
+#endif
#ifdef FEATURE_PERFTRACING
EventPipeAdapter_Shutdown();
DiagnosticServerAdapter_Shutdown();
#endif
}
-#endif
void RuntimeThreadShutdown(void* thread)
{
if (!PalInit())
return false;
-#ifdef _WIN32
+#if defined(_WIN32) || defined(FEATURE_PERFTRACING)
atexit(&OnProcessExit);
#endif
msg->args[i] = data;
}
- ASSERT(IsValid() && threadId == PalGetCurrentThreadIdForLogging());
+ ASSERT(IsValid() && threadId == PalGetCurrentOSThreadId());
}
{
_ASSERTE(pThread != NULL);
//there is no need to zero buffers because we could handle garbage contents
- threadId = PalGetCurrentThreadIdForLogging();
+ threadId = PalGetCurrentOSThreadId();
isDead = FALSE;
curWriteChunk = chunkListTail;
curPtr = (StressMsg *)curWriteChunk->EndPtr ();
// This function is used to get the OS thread identifier for the current thread.
COOP_PINVOKE_HELPER(uint64_t, RhCurrentOSThreadId, ())
{
- return PalGetCurrentThreadIdForLogging();
+ return PalGetCurrentOSThreadId();
}
// Standard calling convention variant and actual implementation for RhpReversePInvokeAttachOrTrapThread
return GCToOSInterface::QueryPerformanceFrequency();
}
-extern "C" uint64_t PalGetCurrentThreadIdForLogging()
+extern "C" uint64_t PalGetCurrentOSThreadId()
{
#if defined(__linux__)
return (uint64_t)syscall(SYS_gettid);
return GCToOSInterface::QueryPerformanceFrequency();
}
-extern "C" uint64_t PalGetCurrentThreadIdForLogging()
+extern "C" uint64_t PalGetCurrentOSThreadId()
{
return GetCurrentThreadId();
}