Skip to content

Commit

Permalink
Add System.Native APIs needed by NativeAOT (#62571)
Browse files Browse the repository at this point in the history
Porting files over from runtimelab branch - no changes to what was there.
  • Loading branch information
MichalStrehovsky authored Dec 10, 2021
1 parent 506463c commit 1996f3d
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/native/libs/Common/pal_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
#cmakedefine01 HAVE_TIOCGWINSZ
#cmakedefine01 HAVE_SCHED_GETAFFINITY
#cmakedefine01 HAVE_SCHED_SETAFFINITY
#cmakedefine01 HAVE_SCHED_GETCPU
#cmakedefine01 HAVE_PTHREAD_SETCANCELSTATE
#cmakedefine01 HAVE_GNU_LIBNAMES_H
#cmakedefine01 HAVE_ARC4RANDOM_BUF
#cmakedefine01 KEVENT_HAS_VOID_UDATA
#cmakedefine01 HAVE_FDS_BITS
Expand Down
7 changes: 7 additions & 0 deletions src/native/libs/System.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CM
add_definitions(-DHAS_CONSOLE_SIGNALS)
endif ()

if (CLR_CMAKE_HOST_ALPINE_LINUX)
# Fix up the thread stack size for MUSL to more reasonable size.
# TODO: https://github.com/dotnet/runtimelab/issues/791
add_definitions(-DENSURE_PRIMARY_STACK_SIZE)
endif ()

if (CLR_CMAKE_TARGET_OSX)
add_definitions(-D_DARWIN_C_SOURCE)
endif ()

set(NATIVE_SOURCES
pal_dynamicload.c
pal_errno.c
pal_interfaceaddresses.c
pal_io.c
Expand Down
8 changes: 8 additions & 0 deletions src/native/libs/System.Native/entrypoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "pal_autoreleasepool.h"
#include "pal_console.h"
#include "pal_datetime.h"
#include "pal_dynamicload.h"
#include "pal_environment.h"
#include "pal_errno.h"
#include "pal_interfaceaddresses.h"
Expand Down Expand Up @@ -235,6 +236,12 @@ static const Entry s_sysNative[] =
DllImportEntry(SystemNative_LowLevelMonitor_Wait)
DllImportEntry(SystemNative_LowLevelMonitor_TimedWait)
DllImportEntry(SystemNative_LowLevelMonitor_Signal_Release)
DllImportEntry(SystemNative_LoadLibrary)
DllImportEntry(SystemNative_GetProcAddress)
DllImportEntry(SystemNative_FreeLibrary)
DllImportEntry(SystemNative_SchedGetCpu)
DllImportEntry(SystemNative_Exit)
DllImportEntry(SystemNative_Abort)
DllImportEntry(SystemNative_UTimensat)
DllImportEntry(SystemNative_GetTimestamp)
DllImportEntry(SystemNative_GetCpuUtilization)
Expand All @@ -253,6 +260,7 @@ static const Entry s_sysNative[] =
DllImportEntry(SystemNative_PWrite)
DllImportEntry(SystemNative_PReadV)
DllImportEntry(SystemNative_PWriteV)
DllImportEntry(SystemNative_RuntimeThread_CreateThread)
DllImportEntry(SystemNative_EnablePosixSignalHandling)
DllImportEntry(SystemNative_DisablePosixSignalHandling)
DllImportEntry(SystemNative_HandleNonCanceledPosixSignal)
Expand Down
52 changes: 52 additions & 0 deletions src/native/libs/System.Native/pal_dynamicload.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "pal_config.h"
#include "pal_dynamicload.h"

#include <dlfcn.h>
#include <string.h>

#if HAVE_GNU_LIBNAMES_H
#include <gnu/lib-names.h>
#endif

void* SystemNative_LoadLibrary(const char* filename)
{
// Check whether we have been requested to load 'libc'. If that's the case, then:
// * For Linux, use the full name of the library that is defined in <gnu/lib-names.h> by the
// LIBC_SO constant. The problem is that calling dlopen("libc.so") will fail for libc even
// though it works for other libraries. The reason is that libc.so is just linker script
// (i.e. a test file).
// As a result, we have to use the full name (i.e. lib.so.6) that is defined by LIBC_SO.
// * For macOS, use constant value absolute path "/usr/lib/libc.dylib".
// * For FreeBSD, use constant value "libc.so.7".
// * For rest of Unices, use constant value "libc.so".
if (strcmp(filename, "libc") == 0)
{
#if defined(__APPLE__)
filename = "/usr/lib/libc.dylib";
#elif defined(__FreeBSD__)
filename = "libc.so.7";
#elif defined(LIBC_SO)
filename = LIBC_SO;
#else
filename = "libc.so";
#endif
}

return dlopen(filename, RTLD_LAZY);
}

void* SystemNative_GetProcAddress(void* handle, const char* symbol)
{
// We're not trying to disambiguate between "symbol was not found" and "symbol found, but
// the value is null". .NET does not define a behavior for DllImports of null entrypoints,
// so we might as well take the "not found" path on the managed side.
return dlsym(handle, symbol);
}

void SystemNative_FreeLibrary(void* handle)
{
dlclose(handle);
}
13 changes: 13 additions & 0 deletions src/native/libs/System.Native/pal_dynamicload.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#pragma once

#include "pal_compiler.h"
#include "pal_types.h"

PALEXPORT void* SystemNative_LoadLibrary(const char* filename);

PALEXPORT void* SystemNative_GetProcAddress(void* handle, const char* symbol);

PALEXPORT void SystemNative_FreeLibrary(void* handle);
71 changes: 71 additions & 0 deletions src/native/libs/System.Native/pal_threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#if HAVE_SCHED_GETCPU
#include <sched.h>
#endif

#if defined(TARGET_OSX)
// So we can use the declaration of pthread_cond_timedwait_relative_np
Expand Down Expand Up @@ -214,3 +217,71 @@ void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor)

(void)error; // unused in release build
}

int32_t SystemNative_RuntimeThread_CreateThread(uintptr_t stackSize, void *(*startAddress)(void*), void *parameter)
{
bool result = false;
pthread_attr_t attrs;

int error = pthread_attr_init(&attrs);
if (error != 0)
{
// Do not call pthread_attr_destroy
return false;
}

error = pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
assert(error == 0);

#ifdef ENSURE_PRIMARY_STACK_SIZE
// TODO: https://github.com/dotnet/runtimelab/issues/791
if (stackSize == 0)
{
stackSize = 1536 * 1024;
}
#endif

if (stackSize > 0)
{
if (stackSize < PTHREAD_STACK_MIN)
{
stackSize = PTHREAD_STACK_MIN;
}

error = pthread_attr_setstacksize(&attrs, stackSize);
if (error != 0) goto CreateThreadExit;
}

pthread_t threadId;
error = pthread_create(&threadId, &attrs, startAddress, parameter);
if (error != 0) goto CreateThreadExit;

result = true;

CreateThreadExit:
error = pthread_attr_destroy(&attrs);
assert(error == 0);

return result;
}

int32_t SystemNative_SchedGetCpu()
{
#if HAVE_SCHED_GETCPU
return sched_getcpu();
#else
return -1;
#endif
}

__attribute__((noreturn))
void SystemNative_Exit(int32_t exitCode)
{
exit(exitCode);
}

__attribute__((noreturn))
void SystemNative_Abort()
{
abort();
}
8 changes: 8 additions & 0 deletions src/native/libs/System.Native/pal_threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ PALEXPORT void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* monitor);
PALEXPORT int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor *monitor, int32_t timeoutMilliseconds);

PALEXPORT void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* monitor);

PALEXPORT int32_t SystemNative_RuntimeThread_CreateThread(uintptr_t stackSize, void *(*startAddress)(void*), void *parameter);

PALEXPORT int32_t SystemNative_SchedGetCpu(void);

PALEXPORT __attribute__((noreturn)) void SystemNative_Exit(int32_t exitCode);

PALEXPORT __attribute__((noreturn)) void SystemNative_Abort(void);
9 changes: 9 additions & 0 deletions src/native/libs/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,20 @@ check_symbol_exists(
"sched.h"
HAVE_SCHED_SETAFFINITY)

check_symbol_exists(
sched_getcpu
"sched.h"
HAVE_SCHED_GETCPU)

check_symbol_exists(
pthread_setcancelstate
"pthread.h"
HAVE_PTHREAD_SETCANCELSTATE)

check_include_files(
gnu/lib-names.h
HAVE_GNU_LIBNAMES_H)

check_symbol_exists(
arc4random_buf
"stdlib.h"
Expand Down

0 comments on commit 1996f3d

Please sign in to comment.