Skip to content

Commit 3db3a8c

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 3db3a8c

File tree

9 files changed

+900
-1
lines changed

9 files changed

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

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)