summaryrefslogtreecommitdiffstats
path: root/toolkit/components/processtools/ProcInfo_solaris.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/processtools/ProcInfo_solaris.cpp')
-rw-r--r--toolkit/components/processtools/ProcInfo_solaris.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/toolkit/components/processtools/ProcInfo_solaris.cpp b/toolkit/components/processtools/ProcInfo_solaris.cpp
new file mode 100644
index 0000000000..c20f731b60
--- /dev/null
+++ b/toolkit/components/processtools/ProcInfo_solaris.cpp
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ProcInfo.h"
+#include "mozilla/Sprintf.h"
+#include "mozilla/Logging.h"
+#include "mozilla/ScopeExit.h"
+#include "mozilla/ipc/GeckoChildProcessHost.h"
+#include "nsMemoryReporterManager.h"
+#include "nsWhitespaceTokenizer.h"
+
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
+#include <fcntl.h>
+#include <procfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+
+// Maximal length on /proc filename
+// "/proc/999999/lwp/999999/lwpsinfo"
+// "/proc/999999/psinfo"
+#define FNMAX_PROCFS "/proc/999999/lwp/999999/lwpsinfo"
+
+namespace mozilla {
+
+int GetCycleTimeFrequencyMHz() { return 0; }
+
+nsresult GetCpuTimeSinceProcessStartInMs(uint64_t* aResult) {
+ timespec t;
+ if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t) == 0) {
+ uint64_t cpuTime =
+ uint64_t(t.tv_sec) * 1'000'000'000u + uint64_t(t.tv_nsec);
+ *aResult = cpuTime / PR_NSEC_PER_MSEC;
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+nsresult GetGpuTimeSinceProcessStartInMs(uint64_t* aResult) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
+ nsTArray<ProcInfoRequest>&& aRequests) {
+ ProcInfoPromise::ResolveOrRejectValue result;
+
+ HashMap<base::ProcessId, ProcInfo> gathered;
+ if (!gathered.reserve(aRequests.Length())) {
+ result.SetReject(NS_ERROR_OUT_OF_MEMORY);
+ return result;
+ }
+ for (const auto& request : aRequests) {
+ ProcInfo info;
+
+ int fd;
+ char filename[sizeof(FNMAX_PROCFS)];
+ psinfo_t psinfo;
+ snprintf(filename, sizeof(FNMAX_PROCFS), "/proc/%d/psinfo", request.pid);
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ result.SetReject(NS_ERROR_FAILURE);
+ return result;
+ }
+ if (read(fd, &psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)) {
+ close(fd);
+ result.SetReject(NS_ERROR_FAILURE);
+ return result;
+ }
+ close(fd);
+ info.cpuTime =
+ psinfo.pr_time.tv_sec * 1'000'000'000u + psinfo.pr_time.tv_nsec;
+ info.memory = psinfo.pr_rssize * 1024;
+
+ // Extra info
+ info.pid = request.pid;
+ info.childId = request.childId;
+ info.type = request.processType;
+ info.origin = request.origin;
+ info.windows = std::move(request.windowInfo);
+ info.utilityActors = std::move(request.utilityInfo);
+
+ // Let's look at the threads
+ for (int lwp = 1, lwp_max = psinfo.pr_nlwp; lwp <= lwp_max; lwp++) {
+ lwpsinfo_t lwpsinfo;
+ snprintf(filename, sizeof(FNMAX_PROCFS), "/proc/%d/lwp/%d/lwpsinfo",
+ request.pid, lwp);
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ // Some LWPs might no longer exist. That just means that there are
+ // probably others with bigger LWP id. But we need to limit the search
+ // because of possible race condition.
+ if (lwp_max < 2 * psinfo.pr_nlwp) lwp_max++;
+ continue;
+ }
+ if (read(fd, &lwpsinfo, sizeof(lwpsinfo_t)) != sizeof(lwpsinfo_t)) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+ ThreadInfo threadInfo;
+ threadInfo.tid = lwpsinfo.pr_lwpid;
+ threadInfo.cpuTime =
+ lwpsinfo.pr_time.tv_sec * 1'000'000'000u + lwpsinfo.pr_time.tv_nsec;
+ threadInfo.name.AssignASCII(lwpsinfo.pr_name, strlen(lwpsinfo.pr_name));
+ info.threads.AppendElement(threadInfo);
+ }
+
+ if (!gathered.put(request.pid, std::move(info))) {
+ result.SetReject(NS_ERROR_OUT_OF_MEMORY);
+ return result;
+ }
+ }
+
+ // ... and we're done!
+ result.SetResolve(std::move(gathered));
+ return result;
+}
+
+} // namespace mozilla