-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove reflection from Environment.WorkingSet prop (#43154)
- Loading branch information
Showing
14 changed files
with
595 additions
and
514 deletions.
There are no files selected for viewing
236 changes: 236 additions & 0 deletions
236
src/libraries/Common/src/Interop/FreeBSD/Interop.Process.GetProcInfo.cs
This file contains 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,236 @@ | ||
// 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 Process | ||
{ | ||
// Constants from sys/user.h | ||
private const int TDNAMLEN = 16; | ||
private const int WMESGLEN = 8; | ||
private const int LOGNAMELEN = 17; | ||
private const int LOCKNAMELEN = 8; | ||
private const int COMMLEN = 19; | ||
private const int KI_EMULNAMELEN = 16; | ||
private const int LOGINCLASSLEN = 17; | ||
private const int KI_NGROUPS = 16; | ||
|
||
private const int KI_NSPARE_INT = 4; | ||
private const int KI_NSPARE_LONG = 12; | ||
private const int KI_NSPARE_PTR = 6; | ||
|
||
// Constants from sys/sysctl.h | ||
private const int CTL_KERN = 1; | ||
private const int KERN_PROC = 14; | ||
private const int KERN_PROC_PROC = 8; | ||
private const int KERN_PROC_PID = 1; | ||
private const int KERN_PROC_INC_THREAD = 16; | ||
|
||
// From sys/_sigset.h | ||
[StructLayout(LayoutKind.Sequential)] | ||
internal unsafe struct sigset_t | ||
{ | ||
private fixed int bits[4]; | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
internal struct uid_t | ||
{ | ||
public uint id; | ||
} | ||
[StructLayout(LayoutKind.Sequential)] | ||
internal struct gid_t | ||
{ | ||
public uint id; | ||
} | ||
[StructLayout(LayoutKind.Sequential)] | ||
public struct timeval | ||
{ | ||
public IntPtr tv_sec; | ||
public IntPtr tv_usec; | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
private struct vnode | ||
{ | ||
public long tv_sec; | ||
public long tv_usec; | ||
} | ||
|
||
// sys/resource.h | ||
[StructLayout(LayoutKind.Sequential)] | ||
internal unsafe struct rusage | ||
{ | ||
public timeval ru_utime; /* user time used */ | ||
public timeval ru_stime; /* system time used */ | ||
public long ru_maxrss; /* max resident set size */ | ||
private long ru_ixrss; /* integral shared memory size */ | ||
private long ru_idrss; /* integral unshared data " */ | ||
private long ru_isrss; /* integral unshared stack " */ | ||
private long ru_minflt; /* page reclaims */ | ||
private long ru_majflt; /* page faults */ | ||
private long ru_nswap; /* swaps */ | ||
private long ru_inblock; /* block input operations */ | ||
private long ru_oublock; /* block output operations */ | ||
private long ru_msgsnd; /* messages sent */ | ||
private long ru_msgrcv; /* messages received */ | ||
private long ru_nsignals; /* signals received */ | ||
private long ru_nvcsw; /* voluntary context switches */ | ||
private long ru_nivcsw; /* involuntary " */ | ||
} | ||
|
||
// From sys/user.h | ||
[StructLayout(LayoutKind.Sequential)] | ||
public unsafe struct kinfo_proc | ||
{ | ||
public int ki_structsize; /* size of this structure */ | ||
private int ki_layout; /* reserved: layout identifier */ | ||
private void* ki_args; /* address of command arguments */ | ||
private void* ki_paddr; /* address of proc */ | ||
private void* ki_addr; /* kernel virtual addr of u-area */ | ||
private vnode* ki_tracep; /* pointer to trace file */ | ||
private vnode* ki_textvp; /* pointer to executable file */ | ||
private void* ki_fd; /* pointer to open file info */ | ||
private void* ki_vmspace; /* pointer to kernel vmspace struct */ | ||
private void* ki_wchan; /* sleep address */ | ||
public int ki_pid; /* Process identifier */ | ||
public int ki_ppid; /* parent process id */ | ||
private int ki_pgid; /* process group id */ | ||
private int ki_tpgid; /* tty process group id */ | ||
public int ki_sid; /* Process session ID */ | ||
public int ki_tsid; /* Terminal session ID */ | ||
private short ki_jobc; /* job control counter */ | ||
private short ki_spare_short1; /* unused (just here for alignment) */ | ||
private int ki_tdev; /* controlling tty dev */ | ||
private sigset_t ki_siglist; /* Signals arrived but not delivered */ | ||
private sigset_t ki_sigmask; /* Current signal mask */ | ||
private sigset_t ki_sigignore; /* Signals being ignored */ | ||
private sigset_t ki_sigcatch; /* Signals being caught by user */ | ||
public uid_t ki_uid; /* effective user id */ | ||
private uid_t ki_ruid; /* Real user id */ | ||
private uid_t ki_svuid; /* Saved effective user id */ | ||
private gid_t ki_rgid; /* Real group id */ | ||
private gid_t ki_svgid; /* Saved effective group id */ | ||
private short ki_ngroups; /* number of groups */ | ||
private short ki_spare_short2; /* unused (just here for alignment) */ | ||
private fixed uint ki_groups[KI_NGROUPS]; /* groups */ | ||
public ulong ki_size; /* virtual size */ | ||
public long ki_rssize; /* current resident set size in pages */ | ||
private long ki_swrss; /* resident set size before last swap */ | ||
private long ki_tsize; /* text size (pages) XXX */ | ||
private long ki_dsize; /* data size (pages) XXX */ | ||
private long ki_ssize; /* stack size (pages) */ | ||
private ushort ki_xstat; /* Exit status for wait & stop signal */ | ||
private ushort ki_acflag; /* Accounting flags */ | ||
private uint ki_pctcpu; /* %cpu for process during ki_swtime */ | ||
private uint ki_estcpu; /* Time averaged value of ki_cpticks */ | ||
private uint ki_slptime; /* Time since last blocked */ | ||
private uint ki_swtime; /* Time swapped in or out */ | ||
private uint ki_cow; /* number of copy-on-write faults */ | ||
private ulong ki_runtime; /* Real time in microsec */ | ||
public timeval ki_start; /* starting time */ | ||
private timeval ki_childtime; /* time used by process children */ | ||
private long ki_flag; /* P_* flags */ | ||
private long ki_kiflag; /* KI_* flags (below) */ | ||
private int ki_traceflag; /* Kernel trace points */ | ||
private byte ki_stat; /* S* process status */ | ||
public byte ki_nice; /* Process "nice" value */ | ||
private byte ki_lock; /* Process lock (prevent swap) count */ | ||
private byte ki_rqindex; /* Run queue index */ | ||
private byte ki_oncpu_old; /* Which cpu we are on (legacy) */ | ||
private byte ki_lastcpu_old; /* Last cpu we were on (legacy) */ | ||
public fixed byte ki_tdname[TDNAMLEN+1]; /* thread name */ | ||
private fixed byte ki_wmesg[WMESGLEN+1]; /* wchan message */ | ||
private fixed byte ki_login[LOGNAMELEN+1]; /* setlogin name */ | ||
private fixed byte ki_lockname[LOCKNAMELEN+1]; /* lock name */ | ||
public fixed byte ki_comm[COMMLEN+1]; /* command name */ | ||
private fixed byte ki_emul[KI_EMULNAMELEN+1]; /* emulation name */ | ||
private fixed byte ki_loginclass[LOGINCLASSLEN+1]; /* login class */ | ||
private fixed byte ki_sparestrings[50]; /* spare string space */ | ||
private fixed int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ | ||
private int ki_oncpu; /* Which cpu we are on */ | ||
private int ki_lastcpu; /* Last cpu we were on */ | ||
private int ki_tracer; /* Pid of tracing process */ | ||
private int ki_flag2; /* P2_* flags */ | ||
private int ki_fibnum; /* Default FIB number */ | ||
private uint ki_cr_flags; /* Credential flags */ | ||
private int ki_jid; /* Process jail ID */ | ||
public int ki_numthreads; /* XXXKSE number of threads in total */ | ||
public int ki_tid; /* XXXKSE thread id */ | ||
private fixed byte ki_pri[4]; /* process priority */ | ||
public rusage ki_rusage; /* process rusage statistics */ | ||
/* XXX - most fields in ki_rusage_ch are not (yet) filled in */ | ||
private rusage ki_rusage_ch; /* rusage of children processes */ | ||
private void* ki_pcb; /* kernel virtual addr of pcb */ | ||
private void* ki_kstack; /* kernel virtual addr of stack */ | ||
private void* ki_udata; /* User convenience pointer */ | ||
public void* ki_tdaddr; /* address of thread */ | ||
|
||
private fixed long ki_spareptrs[KI_NSPARE_PTR]; /* spare room for growth */ | ||
private fixed long ki_sparelongs[KI_NSPARE_LONG]; /* spare room for growth */ | ||
private long ki_sflag; /* PS_* flags */ | ||
private long ki_tdflags; /* XXXKSE kthread flag */ | ||
} | ||
|
||
/// <summary> | ||
/// Gets information about process or thread(s) | ||
/// </summary> | ||
/// <param name="pid">The PID of the process. If PID is 0, this will return all processes</param> | ||
/// <param name="threads">Whether to include thread information.</param> | ||
/// <param name="count">The number of kinfo_proc entries returned.</param> | ||
public static unsafe kinfo_proc* GetProcInfo(int pid, bool threads, out int count) | ||
{ | ||
Span<int> sysctlName = stackalloc int[4]; | ||
int bytesLength = 0; | ||
byte* pBuffer = null; | ||
kinfo_proc* kinfo = null; | ||
int ret; | ||
|
||
count = -1; | ||
|
||
if (pid == 0) | ||
{ | ||
// get all processes | ||
sysctlName[3] = 0; | ||
sysctlName[2] = KERN_PROC_PROC; | ||
} | ||
else | ||
{ | ||
// get specific process, possibly with threads | ||
sysctlName[3] = pid; | ||
sysctlName[2] = KERN_PROC_PID | (threads ? KERN_PROC_INC_THREAD : 0); | ||
} | ||
sysctlName[1] = KERN_PROC; | ||
sysctlName[0] = CTL_KERN; | ||
|
||
try | ||
{ | ||
ret = Interop.Sys.Sysctl(sysctlName, ref pBuffer, ref bytesLength); | ||
if (ret != 0 ) { | ||
throw new ArgumentOutOfRangeException(nameof(pid)); | ||
} | ||
|
||
kinfo = (kinfo_proc*)pBuffer; | ||
if (kinfo->ki_structsize != sizeof(kinfo_proc)) | ||
{ | ||
// failed consistency check | ||
throw new ArgumentOutOfRangeException(nameof(pid)); | ||
} | ||
|
||
count = (int)bytesLength / sizeof(kinfo_proc); | ||
} | ||
catch | ||
{ | ||
Marshal.FreeHGlobal((IntPtr)pBuffer); | ||
throw; | ||
} | ||
|
||
return kinfo; | ||
} | ||
} | ||
} |
Oops, something went wrong.