Skip to content
Open
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
28 changes: 28 additions & 0 deletions src/libraries/Common/src/Interop/Haiku/Interop.OS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class OS
{
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct AreaInfo
{
public nuint size;
public uint ram_size;
}

/// <summary>
/// Gets information about areas owned by a team.
/// </summary>
/// <param name="team">The team ID of the areas to iterate.</param>
/// <param name="cookie">A cookie to track the iteration.</param>
/// <param name="areaInfo">The <see cref="AreaInfo"/> structure to fill in.</param>
/// <returns>Returns 0 on success. Returns an error code on failure or when there are no more areas to iterate.</returns>
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetNextAreaInfo")]
internal static unsafe partial int GetNextAreaInfo(int team, ref nint cookie, out AreaInfo areaInfo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2720,6 +2720,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.iOS.cs" Condition="'$(IsiOSLike)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.OSVersion.Unix.cs" Condition="'$(IsApplePlatform)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.SunOS.cs" Condition="'$(Targetsillumos)' == 'true' or '$(TargetsSolaris)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.Haiku.cs" Condition="'$(TargetsHaiku)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.FullGlobalizationData.Unix.cs" Condition="'$(UseMinimalGlobalizationData)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\DriveInfoInternal.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PersistedFiles.Unix.cs" />
Expand All @@ -2739,6 +2740,11 @@
<ItemGroup Condition="'$(UseMinimalGlobalizationData)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.MinimalGlobalizationData.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsHaiku)' == 'true'">
<Compile Include="$(CommonPath)Interop\Haiku\Interop.OS.cs">
<Link>Common\Interop\Haiku\Interop.OS.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(IsApplePlatform)' == 'true'">
<Compile Include="$(CommonPath)Interop\OSX\Interop.libobjc.cs">
<Link>Common\Interop\OSX\Interop.libobjc.cs</Link>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

namespace System
{
public static partial class Environment
{
public static unsafe long WorkingSet
{
get
{
nint cookie = 0;
long workingSet = 0;

Interop.OS.AreaInfo areaInfo;

while (Interop.OS.GetNextAreaInfo(ProcessId, ref cookie, out areaInfo) == 0)
{
workingSet += areaInfo.ram_size;
}
Comment on lines +14 to +22
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Environment.WorkingSet is queried by runtime metrics/event counters and may be polled frequently. This implementation performs a full area enumeration via SystemNative_GetNextAreaInfo on every call (O(number of areas)), which could become noticeably expensive for processes with many mapped regions. If Haiku exposes a direct API for resident/working set size, prefer that; otherwise consider adding a cheaper fast-path or caching within a short time window to reduce syscall/iteration overhead.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Haiku exposes a direct API for resident/working set size

@waddlesplash Does Haiku expose such an API? team_info doesn't seem to have such a field.

otherwise consider adding a cheaper fast-path or caching within a short time window to reduce syscall/iteration overhead.

On the library level this may cause unintended stale information. I'd say if any counters want this, it's their job to cache.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't at present, no.


return workingSet;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public sealed class OperatingSystem : ISerializable, ICloneable
"ILLUMOS"
#elif TARGET_SOLARIS
"SOLARIS"
#elif TARGET_HAIKU
"HAIKU"
#else
#error Unknown OS, add a corresponding TARGET_* constant to System.Private.CoreLib.Shared.projitems
#endif
Expand Down
1 change: 1 addition & 0 deletions src/native/libs/Common/pal_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
#cmakedefine01 HAVE_NET_IF_H
#cmakedefine01 HAVE_SYS_PROCINFO_H
#cmakedefine01 HAVE_IOSS_H
#cmakedefine01 HAVE_OS_H
#cmakedefine01 HAVE_ALIGNED_ALLOC
#cmakedefine01 HAVE_MALLOC_SIZE
#cmakedefine01 HAVE_MALLOC_USABLE_SIZE
Expand Down
1 change: 1 addition & 0 deletions src/native/libs/System.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ endif ()

set(NATIVE_SOURCES
pal_errno.c
pal_getosinfo.c
pal_io.c
pal_maphardwaretype.c
pal_memory.c
Expand Down
2 changes: 2 additions & 0 deletions src/native/libs/System.Native/entrypoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "pal_dynamicload.h"
#include "pal_environment.h"
#include "pal_errno.h"
#include "pal_getosinfo.h"
#include "pal_interfaceaddresses.h"
#include "pal_io.h"
#include "pal_iossupportversion.h"
Expand Down Expand Up @@ -305,6 +306,7 @@ static const Entry s_sysNative[] =
DllImportEntry(SystemNative_LowLevelCrossProcessMutex_IsAbandoned)
DllImportEntry(SystemNative_LowLevelCrossProcessMutex_SetAbandoned)
DllImportEntry(SystemNative_Select)
DllImportEntry(SystemNative_GetNextAreaInfo)
};

EXTERN_C const void* SystemResolveDllImport(const char* name);
Expand Down
42 changes: 42 additions & 0 deletions src/native/libs/System.Native/pal_getosinfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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_getosinfo.h"
#include "pal_utilities.h"

#include <errno.h>
#include <string.h>

#if HAVE_OS_H
#include <OS.h>
#endif

int32_t SystemNative_GetNextAreaInfo(int32_t team, intptr_t* cookie, AreaInfo* areaInfo)
{
#if HAVE_OS_H
if (cookie == NULL || areaInfo == NULL)
{
return EINVAL;
}

area_info nativeAreaInfo;
memset(&nativeAreaInfo, 0, sizeof(nativeAreaInfo));

status_t status = get_next_area_info((team_id)team, cookie, &nativeAreaInfo);
if (status != B_OK)
{
return (int32_t)status;
}

areaInfo->size = (uintptr_t)nativeAreaInfo.size;
areaInfo->ram_size = (uint32_t)nativeAreaInfo.ram_size;

return (int32_t)status;
#else
(void)team;
(void)cookie;
(void)areaInfo;
return ENOTSUP;
#endif
}
15 changes: 15 additions & 0 deletions src/native/libs/System.Native/pal_getosinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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"

typedef struct
{
uintptr_t size;
uint32_t ram_size;
} AreaInfo;

PALEXPORT int32_t SystemNative_GetNextAreaInfo(int32_t team, intptr_t* cookie, AreaInfo* areaInfo);
4 changes: 4 additions & 0 deletions src/native/libs/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,10 @@ check_include_files(
IOKit/serial/ioss.h
HAVE_IOSS_H)

check_include_files(
OS.h
HAVE_OS_H)

check_symbol_exists(
getpeereid
"unistd.h;sys/types.h;sys/socket.h"
Expand Down
Loading