1 diff --git toolkit/components/processtools/ProcInfo_bsd.cpp toolkit/components/processtools/ProcInfo_bsd.cpp
2 index a6ff4881940c..f041ed5e50ce 100644
3 --- toolkit/components/processtools/ProcInfo_bsd.cpp
4 +++ toolkit/components/processtools/ProcInfo_bsd.cpp
5 @@ -18,6 +18,9 @@
6  #include <cstdio>
7  #include <cstring>
8  #include <unistd.h>
9 +#ifdef __FreeBSD__
10 +#include <sys/user.h>
11 +#endif
12 
13  namespace mozilla {
14 
15 @@ -50,25 +53,39 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
16    }
17    for (const auto& request : aRequests) {
18      size_t size;
19 +#ifdef __FreeBSD__
20 +    int mib[4];
21 +    int mibsize = 4;
22 +    mib[0] = CTL_KERN;
23 +    mib[1] = KERN_PROC;
24 +    mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
25 +    mib[3] = request.pid;
26 +#else
27      int mib[6];
28 +    int mibsize = 6;
29      mib[0] = CTL_KERN;
30      mib[1] = KERN_PROC;
31      mib[2] = KERN_PROC_PID | KERN_PROC_SHOW_THREADS;
32      mib[3] = request.pid;
33      mib[4] = sizeof(kinfo_proc);
34      mib[5] = 0;
35 -    if (sysctl(mib, 6, nullptr, &size, nullptr, 0) == -1) {
36 +#endif
37 +    if (sysctl(mib, mibsize, nullptr, &size, nullptr, 0) == -1) {
38        // Can't get info for this process. Skip it.
39        continue;
40      }
41 
42 +#ifdef __FreeBSD__
43 +    auto procs = MakeUniqueFallible<kinfo_proc[]>(size / sizeof(kinfo_proc));
44 +#else
45      mib[5] = size / sizeof(kinfo_proc);
46      auto procs = MakeUniqueFallible<kinfo_proc[]>(mib[5]);
47 +#endif
48      if (!procs) {
49        result.SetReject(NS_ERROR_OUT_OF_MEMORY);
50        return result;
51      }
52 -    if (sysctl(mib, 6, procs.get(), &size, nullptr, 0) == -1 &&
53 +    if (sysctl(mib, mibsize, procs.get(), &size, nullptr, 0) == -1 &&
54          errno != ENOMEM) {
55        continue;
56      }
57 @@ -84,19 +101,34 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
58      bool found = false;
59      for (size_t i = 0; i < size / sizeof(kinfo_proc); i++) {
60        const auto& p = procs[i];
61 +#ifdef __FreeBSD__
62 +      if (i == 0) {
63 +#else
64        if (p.p_tid == -1) {
65 +#endif
66          // This is the process.
67          found = true;
68 +#ifdef __FreeBSD__
69 +        info.cpuTime = uint64_t(p.ki_runtime) * 1'000u;
70 +        info.memory = (p.ki_tsize + p.ki_dsize + p.ki_ssize) * getpagesize();
71 +#else
72          info.cpuTime = uint64_t(p.p_rtime_sec) * 1'000'000'000u +
73                         uint64_t(p.p_rtime_usec) * 1'000u;
74          info.memory =
75              (p.p_vm_tsize + p.p_vm_dsize + p.p_vm_ssize) * getpagesize();
76 +#endif
77 +
78        } else {
79          // This is one of its threads.
80          ThreadInfo threadInfo;
81 +#ifdef __FreeBSD__
82 +        threadInfo.tid = p.ki_tid;
83 +        threadInfo.cpuTime = uint64_t(p.ki_runtime) * 1'000u;
84 +#else
85          threadInfo.tid = p.p_tid;
86          threadInfo.cpuTime = uint64_t(p.p_rtime_sec) * 1'000'000'000u +
87                               uint64_t(p.p_rtime_usec) * 1'000u;
88 +#endif
89          info.threads.AppendElement(threadInfo);
90        }
91      }
92 diff --git toolkit/components/processtools/moz.build toolkit/components/processtools/moz.build
93 index b7c164c1b0ac..a41dad52c343 100644
94 --- toolkit/components/processtools/moz.build
95 +++ toolkit/components/processtools/moz.build
96 @@ -39,7 +39,7 @@ BROWSER_CHROME_MANIFESTS += ["tests/browser/browser.ini"]
97  # Platform-specific implementations of `ProcInfo`.
98  toolkit = CONFIG["MOZ_WIDGET_TOOLKIT"]
99  if toolkit == "gtk" or toolkit == "android":
100 -    if CONFIG["OS_TARGET"] == "OpenBSD":
101 +    if CONFIG["OS_TARGET"] == "FreeBSD" or CONFIG["OS_TARGET"] == "OpenBSD":
102          UNIFIED_SOURCES += ["ProcInfo_bsd.cpp"]
103      else:
104          UNIFIED_SOURCES += ["ProcInfo_linux.cpp"]
105