Skip to content

Commit 822ecd1

Browse files
trungnt2910jessicah
andcommitted
Haiku: Process/thread management functions
Add support for process/thread management functions in `System.Diagnostics.Process` for Haiku. This is required to build managed runtime libraries for Haiku as well as running a simple "Hello, World!" application. Co-authored-by: Jessica Hamilton <jessica.l.hamilton@gmail.com>
1 parent c582fa2 commit 822ecd1

File tree

9 files changed

+899
-1
lines changed

9 files changed

+899
-1
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
7+
#pragma warning disable CA1823 // analyzer incorrectly flags fixed buffer length const (https://github.com/dotnet/roslyn/issues/37593)
8+
9+
internal static partial class Interop
10+
{
11+
internal static partial class Image
12+
{
13+
internal const int MAXPATHLEN = 1024;
14+
15+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
16+
private static unsafe partial int _get_next_image_info(int team, ref int cookie, out image_info info, nuint size);
17+
18+
internal enum image_type
19+
{
20+
B_APP_IMAGE = 1,
21+
B_LIBRARY_IMAGE,
22+
B_ADD_ON_IMAGE,
23+
B_SYSTEM_IMAGE,
24+
}
25+
26+
[StructLayout(LayoutKind.Sequential)]
27+
internal unsafe struct image_info
28+
{
29+
public int id;
30+
public image_type type;
31+
public int sequence;
32+
public int init_order;
33+
public delegate* unmanaged<void> init_routine;
34+
public delegate* unmanaged<void> term_routine;
35+
public int device;
36+
public long node;
37+
public fixed byte name[MAXPATHLEN];
38+
public void* text;
39+
public void* data;
40+
public int text_size;
41+
public int data_size;
42+
public int api_version;
43+
public int abi;
44+
}
45+
46+
/// <summary>
47+
/// Gets information about images owned by a team.
48+
/// </summary>
49+
/// <param name="team">The team ID to iterate.</param>
50+
/// <param name="cookie">A cookie to track the iteration.</param>
51+
/// <param name="info">The <see cref="image_info"/> structure to fill in.</param>
52+
/// <returns>Returns 0 on success. Returns an error code on failure or when there are no more images to iterate.</returns>
53+
internal static unsafe int GetNextImageInfo(int team, ref int cookie, out image_info info)
54+
{
55+
return _get_next_image_info(team, ref cookie, out info, (nuint)sizeof(image_info));
56+
}
57+
}
58+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
internal static partial class Interop
5+
{
6+
internal static partial class Libraries
7+
{
8+
internal const string libroot = "libroot";
9+
}
10+
}
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
7+
#pragma warning disable CA1823 // analyzer incorrectly flags fixed buffer length const (https://github.com/dotnet/roslyn/issues/37593)
8+
9+
internal static partial class Interop
10+
{
11+
internal static partial class OS
12+
{
13+
internal const int B_OS_NAME_LENGTH = 32;
14+
internal const int B_FILE_NAME_LENGTH = 256;
15+
16+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
17+
private static unsafe partial int _get_next_area_info(int team, ref nint cookie, out area_info areaInfo, nuint size);
18+
19+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
20+
private static unsafe partial int _get_team_info(int id, out team_info info, nuint size);
21+
22+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
23+
private static unsafe partial int _get_next_team_info(ref int cookie, void* info, nuint size);
24+
25+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
26+
private static unsafe partial int _get_team_usage_info(int team, BTeamUsage who, out team_usage_info info, nuint size);
27+
28+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
29+
private static unsafe partial int _get_thread_info(int id, out thread_info info, nuint size);
30+
31+
[LibraryImportAttribute(Interop.Libraries.libroot, SetLastError = false)]
32+
private static unsafe partial int _get_next_thread_info(int team, ref int cookie, out thread_info info, nuint size);
33+
34+
[StructLayout(LayoutKind.Sequential)]
35+
internal unsafe struct area_info
36+
{
37+
public int area;
38+
public fixed byte name[B_OS_NAME_LENGTH];
39+
public nuint size;
40+
public uint @lock;
41+
public uint protection;
42+
public int team;
43+
public uint ram_size;
44+
public uint copy_count;
45+
public uint in_count;
46+
public uint out_count;
47+
public void* address;
48+
}
49+
50+
[StructLayout(LayoutKind.Sequential)]
51+
internal unsafe struct team_info
52+
{
53+
public int team;
54+
public int thread_count;
55+
public int image_count;
56+
public int area_count;
57+
public int debugger_nub_thread;
58+
public int debugger_nub_port;
59+
public int argc;
60+
public fixed byte args[64];
61+
public uint uid;
62+
public uint gid;
63+
public uint real_uid;
64+
public uint real_gid;
65+
public int group_id;
66+
public int session_id;
67+
public int parent;
68+
public fixed byte name[B_OS_NAME_LENGTH];
69+
public long start_time;
70+
}
71+
72+
internal enum BTeamUsage
73+
{
74+
B_TEAM_USAGE_SELF = 0,
75+
B_TEAM_USAGE_CHILDREN = -1,
76+
}
77+
78+
[StructLayout(LayoutKind.Sequential)]
79+
internal struct team_usage_info
80+
{
81+
public long user_time;
82+
public long kernel_time;
83+
}
84+
85+
internal enum thread_state
86+
{
87+
B_THREAD_RUNNING = 1,
88+
B_THREAD_READY,
89+
B_THREAD_RECEIVING,
90+
B_THREAD_ASLEEP,
91+
B_THREAD_SUSPENDED,
92+
B_THREAD_WAITING,
93+
}
94+
95+
[StructLayout(LayoutKind.Sequential)]
96+
internal unsafe struct thread_info
97+
{
98+
public int thread;
99+
public int team;
100+
public fixed byte name[B_OS_NAME_LENGTH];
101+
public thread_state state;
102+
public int priority;
103+
public int sem;
104+
public long user_time;
105+
public long kernel_time;
106+
public void* stack_base;
107+
public void* stack_end;
108+
}
109+
110+
internal enum BPriority
111+
{
112+
B_IDLE_PRIORITY = 0,
113+
B_LOWEST_ACTIVE_PRIORITY = 1,
114+
B_LOW_PRIORITY = 5,
115+
B_NORMAL_PRIORITY = 10,
116+
B_DISPLAY_PRIORITY = 15,
117+
B_URGENT_DISPLAY_PRIORITY = 20,
118+
B_REAL_TIME_DISPLAY_PRIORITY = 100,
119+
B_URGENT_PRIORITY = 110,
120+
B_REAL_TIME_PRIORITY = 120,
121+
}
122+
123+
[StructLayout(LayoutKind.Sequential)]
124+
internal unsafe struct system_info
125+
{
126+
public long boot_time;
127+
public uint cpu_count;
128+
public ulong max_pages;
129+
public ulong used_pages;
130+
public ulong cached_pages;
131+
public ulong block_cache_pages;
132+
public ulong ignored_pages;
133+
public ulong needed_memory;
134+
public ulong free_memory;
135+
public ulong max_swap_pages;
136+
public ulong free_swap_pages;
137+
public uint page_faults;
138+
public uint max_sems;
139+
public uint used_sems;
140+
public uint max_ports;
141+
public uint used_ports;
142+
public uint max_threads;
143+
public uint used_threads;
144+
public uint max_teams;
145+
public uint used_teams;
146+
public fixed byte kernel_name[B_FILE_NAME_LENGTH];
147+
public fixed byte kernel_build_date[B_OS_NAME_LENGTH];
148+
public fixed byte kernel_build_time[B_OS_NAME_LENGTH];
149+
public long kernel_version;
150+
public uint abi;
151+
}
152+
153+
/// <summary>
154+
/// Gets information about areas owned by a team.
155+
/// </summary>
156+
/// <param name="team">The team ID of the areas to iterate.</param>
157+
/// <param name="cookie">A cookie to track the iteration.</param>
158+
/// <param name="info">The <see cref="area_info"/> structure to fill in.</param>
159+
/// <returns>Returns 0 on success. Returns an error code on failure or when there are no more areas to iterate.</returns>
160+
internal static unsafe int GetNextAreaInfo(int team, ref nint cookie, out area_info info)
161+
{
162+
return _get_next_area_info(team, ref cookie, out info, (nuint)sizeof(area_info));
163+
}
164+
165+
/// <summary>
166+
/// Gets information about a team.
167+
/// </summary>
168+
/// <param name="team">The team ID.</param>
169+
/// <param name="info">The <see cref="team_info"/> structure to fill in.</param>
170+
/// <returns>Returns 0 on success or an error code on failure.</returns>
171+
internal static unsafe int GetTeamInfo(int team, out team_info info)
172+
{
173+
return _get_team_info(team, out info, (nuint)sizeof(team_info));
174+
}
175+
176+
/// <summary>
177+
/// Gets information about teams.
178+
/// </summary>
179+
/// <param name="cookie">A cookie to track the iteration.</param>
180+
/// <param name="info">The <see cref="team_info"/> structure to fill in.</param>
181+
/// <returns>Returns 0 on success. Returns an error code on failure or when there are no more teams to iterate.</returns>
182+
internal static unsafe int GetNextTeamInfo(ref int cookie, out team_info info)
183+
{
184+
fixed (team_info* p = &info)
185+
{
186+
return _get_next_team_info(ref cookie, p, (nuint)sizeof(team_info));
187+
}
188+
}
189+
190+
/// <summary>
191+
/// Gets team IDs.
192+
/// </summary>
193+
/// <param name="cookie">A cookie to track the iteration.</param>
194+
/// <param name="team">The integer to store the retrieved team ID.</param>
195+
/// <returns>Returns 0 on success. Returns an error code on failure or when there are no more teams to iterate.</returns>
196+
internal static unsafe int GetNextTeamId(ref int cookie, out int team)
197+
{
198+
fixed (int* p = &team)
199+
{
200+
return _get_next_team_info(ref cookie, p, (nuint)sizeof(int));
201+
}
202+
}
203+
204+
/// <summary>
205+
/// Gets information about a team's usage.
206+
/// </summary>
207+
/// <param name="team">The team ID.</param>
208+
/// <param name="who">Specifies whether to get usage information for the team or its children.</param>
209+
/// <param name="info">The <see cref="team_usage_info"/> structure to fill in.</param>
210+
/// <returns>Returns 0 on success or an error code on failure.</returns>
211+
internal static unsafe int GetTeamUsageInfo(int team, BTeamUsage who, out team_usage_info info)
212+
{
213+
return _get_team_usage_info(team, who, out info, (nuint)sizeof(team_usage_info));
214+
}
215+
216+
/// <summary>
217+
/// Sets the priority of a thread.
218+
/// </summary>
219+
/// <param name="thread">The thread ID.</param>
220+
/// <param name="newPriority">The new priority.</param>
221+
/// <returns>The previous priority if successful or an error code on failure.</returns>
222+
[LibraryImportAttribute(Interop.Libraries.libroot, EntryPoint = "set_thread_priority", SetLastError = false)]
223+
internal static unsafe partial int SetThreadPriority(int thread, int newPriority);
224+
225+
/// <summary>
226+
/// Gets information about a thread.
227+
/// </summary>
228+
/// <param name="thread">The thread ID.</param>
229+
/// <param name="info">The <see cref="thread_info"/> structure to fill in.</param>
230+
/// <returns>Returns 0 on success or an error code on failure.</returns>
231+
internal static unsafe int GetThreadInfo(int thread, out thread_info info)
232+
{
233+
return _get_thread_info(thread, out info, (nuint)sizeof(thread_info));
234+
}
235+
236+
/// <summary>
237+
/// Gets information about threads owned by a team.
238+
/// </summary>
239+
/// <param name="team">The team ID of the threads to iterate.</param>
240+
/// <param name="cookie">A cookie to track the iteration.</param>
241+
/// <param name="info">The <see cref="thread_info"/> structure to fill in.</param>
242+
/// <returns>Returns 0 on success. Returns an error code on failure or when there are no more threads to iterate.</returns>
243+
internal static unsafe int GetNextThreadInfo(int team, ref int cookie, out thread_info info)
244+
{
245+
return _get_next_thread_info(team, ref cookie, out info, (nuint)sizeof(thread_info));
246+
}
247+
248+
/// <summary>
249+
/// Gets information about the system.
250+
/// </summary>
251+
/// <param name="info">The system_info to store retrieved information.</param>
252+
/// <returns>0 if successful.</returns>
253+
[LibraryImportAttribute(Interop.Libraries.libroot, EntryPoint = "get_system_info", SetLastError = false)]
254+
internal static unsafe partial int GetSystemInfo(out system_info info);
255+
}
256+
}

src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-freebsd;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-maccatalyst;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)</TargetFrameworks>
4+
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-freebsd;$(NetCoreAppCurrent)-haiku;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-maccatalyst;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)</TargetFrameworks>
55
<DefineConstants>$(DefineConstants);FEATURE_REGISTRY</DefineConstants>
66
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
77
<UseCompilerGeneratedDocXmlFile>false</UseCompilerGeneratedDocXmlFile>
@@ -369,6 +369,18 @@
369369
Link="Common\Interop\FreeBSD\Interop.Process.GetProcInfo.cs" />
370370
</ItemGroup>
371371

372+
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'haiku'">
373+
<Compile Include="System\Diagnostics\Process.Haiku.cs" />
374+
<Compile Include="System\Diagnostics\ProcessManager.Haiku.cs" />
375+
<Compile Include="System\Diagnostics\ProcessThread.Haiku.cs" />
376+
<Compile Include="$(CommonPath)Interop\Haiku\Interop.Image.cs"
377+
Link="Common\Interop\Haiku\Interop.Image.cs" />
378+
<Compile Include="$(CommonPath)Interop\Haiku\Interop.Libraries.cs"
379+
Link="Common\Interop\Haiku\Interop.Libraries.cs" />
380+
<Compile Include="$(CommonPath)Interop\Haiku\Interop.OS.cs"
381+
Link="Common\Interop\Haiku\Interop.OS.cs" />
382+
</ItemGroup>
383+
372384
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'ios' or '$(TargetPlatformIdentifier)' == 'tvos'">
373385
<Compile Include="System\Diagnostics\Process.iOS.cs" />
374386
<Compile Include="System\Diagnostics\ProcessManager.iOS.cs" />

0 commit comments

Comments
 (0)