-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Haiku: Process/thread management functions #121883
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
Open
trungnt2910
wants to merge
3
commits into
dotnet:main
Choose a base branch
from
trungnt2910:dev/trungnt2910/haiku-lib-diagnostics
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| // 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; | ||
|
|
||
| #pragma warning disable CA1823 // analyzer incorrectly flags fixed buffer length const (https://github.com/dotnet/roslyn/issues/37593) | ||
|
|
||
| internal static partial class Interop | ||
| { | ||
| internal static partial class Image | ||
| { | ||
| internal const int MAXPATHLEN = 1024; | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_next_image_info(int team, ref int cookie, out image_info info, nuint size); | ||
|
|
||
| internal enum image_type : int | ||
| { | ||
| B_APP_IMAGE = 1, | ||
| B_LIBRARY_IMAGE, | ||
| B_ADD_ON_IMAGE, | ||
| B_SYSTEM_IMAGE, | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct image_info | ||
| { | ||
| public int id; | ||
| public image_type type; | ||
| public int sequence; | ||
| public int init_order; | ||
| public delegate* unmanaged<void> init_routine; | ||
| public delegate* unmanaged<void> term_routine; | ||
| public int device; | ||
| public long node; | ||
| public fixed byte name[MAXPATHLEN]; | ||
| public void* text; | ||
| public void* data; | ||
| public int text_size; | ||
| public int data_size; | ||
| public int api_version; | ||
| public int abi; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets information about images owned by a team. | ||
| /// </summary> | ||
| /// <param name="team">The team ID to iterate.</param> | ||
| /// <param name="cookie">A cookie to track the iteration.</param> | ||
| /// <param name="info">The <see cref="image_info"/> structure to fill in.</param> | ||
| /// <returns>Returns 0 on success. Returns an error code on failure or when there are no more images to iterate.</returns> | ||
| internal static unsafe int GetNextImageInfo(int team, ref int cookie, out image_info info) | ||
| { | ||
| return _get_next_image_info(team, ref cookie, out info, (nuint)sizeof(image_info)); | ||
| } | ||
| } | ||
| } | ||
10 changes: 10 additions & 0 deletions
10
src/libraries/Common/src/Interop/Haiku/Interop.Libraries.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| internal static partial class Interop | ||
| { | ||
| internal static partial class Libraries | ||
| { | ||
| internal const string libroot = "libroot"; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,256 @@ | ||
| // 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; | ||
|
|
||
| #pragma warning disable CA1823 // analyzer incorrectly flags fixed buffer length const (https://github.com/dotnet/roslyn/issues/37593) | ||
|
|
||
| internal static partial class Interop | ||
| { | ||
| internal static partial class OS | ||
| { | ||
| internal const int B_OS_NAME_LENGTH = 32; | ||
| internal const int B_FILE_NAME_LENGTH = 256; | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_next_area_info(int team, ref nint cookie, out area_info areaInfo, nuint size); | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_team_info(int id, out team_info info, nuint size); | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_next_team_info(ref int cookie, void* info, nuint size); | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_team_usage_info(int team, BTeamUsage who, out team_usage_info info, nuint size); | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_thread_info(int id, out thread_info info, nuint size); | ||
|
|
||
| [LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)] | ||
| private static unsafe partial int _get_next_thread_info(int team, ref int cookie, out thread_info info, nuint size); | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct area_info | ||
| { | ||
| public int area; | ||
| public fixed byte name[B_OS_NAME_LENGTH]; | ||
| public nuint size; | ||
| public uint @lock; | ||
| public uint protection; | ||
| public int team; | ||
| public uint ram_size; | ||
| public uint copy_count; | ||
| public uint in_count; | ||
| public uint out_count; | ||
| public void* address; | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct team_info | ||
| { | ||
| public int team; | ||
| public int thread_count; | ||
| public int image_count; | ||
| public int area_count; | ||
| public int debugger_nub_thread; | ||
| public int debugger_nub_port; | ||
| public int argc; | ||
| public fixed byte args[64]; | ||
| public uint uid; | ||
| public uint gid; | ||
| public uint real_uid; | ||
| public uint real_gid; | ||
| public int group_id; | ||
| public int session_id; | ||
| public int parent; | ||
| public fixed byte name[B_OS_NAME_LENGTH]; | ||
| public long start_time; | ||
| } | ||
|
|
||
| internal enum BTeamUsage : int | ||
| { | ||
| B_TEAM_USAGE_SELF = 0, | ||
| B_TEAM_USAGE_CHILDREN = -1, | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal struct team_usage_info | ||
| { | ||
| public long user_time; | ||
| public long kernel_time; | ||
| } | ||
|
|
||
| internal enum thread_state : int | ||
| { | ||
| B_THREAD_RUNNING = 1, | ||
| B_THREAD_READY, | ||
| B_THREAD_RECEIVING, | ||
| B_THREAD_ASLEEP, | ||
| B_THREAD_SUSPENDED, | ||
| B_THREAD_WAITING, | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct thread_info | ||
| { | ||
| public int thread; | ||
| public int team; | ||
| public fixed byte name[B_OS_NAME_LENGTH]; | ||
| public thread_state state; | ||
| public int priority; | ||
| public int sem; | ||
| public long user_time; | ||
| public long kernel_time; | ||
| public void* stack_base; | ||
| public void* stack_end; | ||
| } | ||
|
|
||
| internal enum BPriority : int | ||
| { | ||
| B_IDLE_PRIORITY = 0, | ||
| B_LOWEST_ACTIVE_PRIORITY = 1, | ||
| B_LOW_PRIORITY = 5, | ||
| B_NORMAL_PRIORITY = 10, | ||
| B_DISPLAY_PRIORITY = 15, | ||
| B_URGENT_DISPLAY_PRIORITY = 20, | ||
| B_REAL_TIME_DISPLAY_PRIORITY = 100, | ||
| B_URGENT_PRIORITY = 110, | ||
| B_REAL_TIME_PRIORITY = 120, | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct system_info | ||
| { | ||
| public long boot_time; | ||
| public uint cpu_count; | ||
| public ulong max_pages; | ||
| public ulong used_pages; | ||
| public ulong cached_pages; | ||
| public ulong block_cache_pages; | ||
| public ulong ignored_pages; | ||
| public ulong needed_memory; | ||
| public ulong free_memory; | ||
| public ulong max_swap_pages; | ||
| public ulong free_swap_pages; | ||
| public uint page_faults; | ||
| public uint max_sems; | ||
| public uint used_sems; | ||
| public uint max_ports; | ||
| public uint used_ports; | ||
| public uint max_threads; | ||
| public uint used_threads; | ||
| public uint max_teams; | ||
| public uint used_teams; | ||
| public fixed byte kernel_name[B_FILE_NAME_LENGTH]; | ||
| public fixed byte kernel_build_date[B_OS_NAME_LENGTH]; | ||
| public fixed byte kernel_build_time[B_OS_NAME_LENGTH]; | ||
| public long kernel_version; | ||
| public uint abi; | ||
| } | ||
|
|
||
| /// <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="info">The <see cref="area_info"/> 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> | ||
| internal static unsafe int GetNextAreaInfo(int team, ref nint cookie, out area_info info) | ||
| { | ||
| return _get_next_area_info(team, ref cookie, out info, (nuint)sizeof(area_info)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets information about a team. | ||
| /// </summary> | ||
| /// <param name="team">The team ID.</param> | ||
| /// <param name="info">The <see cref="team_info"/> structure to fill in.</param> | ||
| /// <returns>Returns 0 on success or an error code on failure.</returns> | ||
| internal static unsafe int GetTeamInfo(int team, out team_info info) | ||
| { | ||
| return _get_team_info(team, out info, (nuint)sizeof(team_info)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets information about teams. | ||
| /// </summary> | ||
| /// <param name="cookie">A cookie to track the iteration.</param> | ||
| /// <param name="info">The <see cref="team_info"/> structure to fill in.</param> | ||
| /// <returns>Returns 0 on success. Returns an error code on failure or when there are no more teams to iterate.</returns> | ||
| internal static unsafe int GetNextTeamInfo(ref int cookie, out team_info info) | ||
| { | ||
| fixed (team_info* p = &info) | ||
| { | ||
| return _get_next_team_info(ref cookie, p, (nuint)sizeof(team_info)); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets team IDs. | ||
| /// </summary> | ||
| /// <param name="cookie">A cookie to track the iteration.</param> | ||
| /// <param name="team">The integer to store the retrieved team ID.</param> | ||
| /// <returns>Returns 0 on success. Returns an error code on failure or when there are no more teams to iterate.</returns> | ||
| internal static unsafe int GetNextTeamId(ref int cookie, out int team) | ||
| { | ||
| fixed (int* p = &team) | ||
| { | ||
| return _get_next_team_info(ref cookie, p, (nuint)sizeof(int)); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets information about a team's usage. | ||
| /// </summary> | ||
| /// <param name="team">The team ID.</param> | ||
| /// <param name="who">Specifies whether to get usage information for the team or its children.</param> | ||
| /// <param name="info">The <see cref="team_usage_info"/> structure to fill in.</param> | ||
| /// <returns>Returns 0 on success or an error code on failure.</returns> | ||
| internal static unsafe int GetTeamUsageInfo(int team, BTeamUsage who, out team_usage_info info) | ||
| { | ||
| return _get_team_usage_info(team, who, out info, (nuint)sizeof(team_usage_info)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Sets the priority of a thread. | ||
| /// </summary> | ||
| /// <param name="thread">The thread ID.</param> | ||
| /// <param name="newPriority">The new priority.</param> | ||
| /// <returns>The previous priority if successful or an error code on failure.</returns> | ||
| [LibraryImportAttribute(Interop.Libraries.libroot, EntryPoint = "set_thread_priority", SetLastError = false)] | ||
| internal static unsafe partial int SetThreadPriority(int thread, int newPriority); | ||
|
|
||
| /// <summary> | ||
| /// Gets information about a thread. | ||
| /// </summary> | ||
| /// <param name="thread">The thread ID.</param> | ||
| /// <param name="info">The <see cref="thread_info"/> structure to fill in.</param> | ||
| /// <returns>Returns 0 on success or an error code on failure.</returns> | ||
| internal static unsafe int GetThreadInfo(int thread, out thread_info info) | ||
| { | ||
| return _get_thread_info(thread, out info, (nuint)sizeof(thread_info)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets information about threads owned by a team. | ||
| /// </summary> | ||
| /// <param name="team">The team ID of the threads to iterate.</param> | ||
| /// <param name="cookie">A cookie to track the iteration.</param> | ||
| /// <param name="info">The <see cref="thread_info"/> structure to fill in.</param> | ||
| /// <returns>Returns 0 on success. Returns an error code on failure or when there are no more threads to iterate.</returns> | ||
| internal static unsafe int GetNextThreadInfo(int team, ref int cookie, out thread_info info) | ||
| { | ||
| return _get_next_thread_info(team, ref cookie, out info, (nuint)sizeof(thread_info)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets information about the system. | ||
| /// </summary> | ||
| /// <param name="info">The system_info to store retrieved information.</param> | ||
| /// <returns>0 if successful.</returns> | ||
| [LibraryImportAttribute(Interop.Libraries.libroot, EntryPoint = "get_system_info", SetLastError = false)] | ||
| internal static unsafe partial int GetSystemInfo(out system_info info); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: if it's not interested to invoke them from managed code, you can define them as opaque
IntPtr.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe an opaque
void*instead, since the other members arevoid*?Those two correspond to https://github.com/haiku/haiku/blob/d39ce117e02d3d8aac966b1a46bd955a2b59c069/headers/os/kernel/image.h#L27-L28 in the Haiku source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semantic-wise
void*is incorrect because function pointers can't be dereferenced. In C function pointers can't be casted tovoid*either.IntPtris correct for opaque pointer-size field. Unmanaged function pointer is precise but unnecessary.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is theoretically non-portable since C allows data pointers and function pointers to have different sizes. There are no mainstream platforms like that. C compilers do not even produce a warning for casting function pointer to void*.
If .NET got ported to a platform where data pointers and function pointers have different sizes, C#, IL, and number of .NET APIs would have a problem....
It is about as unnecessary as using the actual name for the field. It would save a few bytes in the IL binary. Function pointer types are not hydrated unless they are actually needed by e.g. reflection, so there is no runtime overhead from using actual type here.
We prefer to use actual names and actual types even if it means a few extra bytes in the binary. From https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices: DO use .NET types that map closest to the native type.