[PATCH v3] server: implement vm counters on FreeBSD

Damjan Jovanovic damjan.jov at gmail.com
Thu Nov 18 23:19:27 CST 2021


Try 3 uses libprocstat in a new file, procstat.c
(just like Solaris's procfs.c), which allows greater control
over the included headers, so the duplicate definition
of 'struct thread' can be avoided.

Signed-off-by: Damjan Jovanovic <damjan.jov at gmail.com>
---
 server/Makefile.in |  3 +-
 server/process.c   |  7 ++--
 server/process.h   |  4 +++
 server/procstat.c  | 83 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 3 deletions(-)
 create mode 100644 server/procstat.c
-------------- next part --------------
diff --git a/server/Makefile.in b/server/Makefile.in
index 84e78d0aa56..4c4dedcb35a 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -25,6 +25,7 @@ C_SRCS = \
 	object.c \
 	process.c \
 	procfs.c \
+	procstat.c \
 	ptrace.c \
 	queue.c \
 	region.c \
@@ -49,6 +50,6 @@ MANPAGES = \
 	wineserver.fr.UTF-8.man.in \
 	wineserver.man.in
 
-EXTRALIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS)
+EXTRALIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS)
 
 unicode_EXTRADEFS = -DNLSDIR="\"${nlsdir}\"" -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${nlsdir}`\"
diff --git a/server/process.c b/server/process.c
index 343ad78270c..76d42f82261 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1550,9 +1550,9 @@ DECL_HANDLER(get_process_vm_counters)
     struct process *process = get_process_from_handle( req->handle, PROCESS_QUERY_LIMITED_INFORMATION );
 
     if (!process) return;
-#ifdef linux
     if (process->unix_pid != -1)
     {
+#ifdef linux
         FILE *f;
         char proc_path[32], line[256];
         unsigned long value;
@@ -1579,9 +1579,12 @@ DECL_HANDLER(get_process_vm_counters)
             fclose( f );
         }
         else set_error( STATUS_ACCESS_DENIED );
+#elif defined(HAVE_LIBPROCSTAT)
+        unsigned int err = procstat_get_process_vm_counters( process->unix_pid, reply );
+        if (err) set_error( err );
+#endif
     }
     else set_error( STATUS_ACCESS_DENIED );
-#endif
     release_object( process );
 }
 
diff --git a/server/process.h b/server/process.h
index 22ee8178368..b64299f9f8f 100644
--- a/server/process.h
+++ b/server/process.h
@@ -146,4 +146,8 @@ static inline int is_process_init_done( struct process *process )
 
 static const unsigned int default_session_id = 1;
 
+#ifdef HAVE_LIBPROCSTAT
+extern unsigned int procstat_get_process_vm_counters(pid_t pid, struct get_process_vm_counters_reply *reply);
+#endif
+
 #endif  /* __WINE_SERVER_PROCESS_H */
diff --git a/server/procstat.c b/server/procstat.c
new file mode 100644
index 00000000000..a0f882a6029
--- /dev/null
+++ b/server/procstat.c
@@ -0,0 +1,83 @@
+/*
+ * libprocstat support for FreeBSD
+ *
+ * Copyright (C) 2021 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_QUEUE_H
+# include <sys/queue.h>
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+#endif
+
+#ifdef HAVE_SYS_USER_H
+# include <sys/user.h>
+#endif
+#ifdef HAVE_LIBPROCSTAT
+# include <libprocstat.h>
+#endif
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "file.h"
+#include "process.h"
+/* DO NOT include "thread.h", another "struct thread" is defined in <sys/user.h> */
+
+#ifdef HAVE_LIBPROCSTAT
+
+unsigned int procstat_get_process_vm_counters(pid_t pid, struct get_process_vm_counters_reply *reply)
+{
+    struct procstat *procstat;
+    unsigned int count;
+    unsigned int ret = 0;
+
+    if ((procstat = procstat_open_sysctl()))
+    {
+        struct kinfo_proc *kp = procstat_getprocs( procstat, KERN_PROC_PID, pid, &count );
+        if (kp)
+        {
+            reply->virtual_size = kp->ki_size;
+            reply->peak_virtual_size = reply->virtual_size;
+            reply->working_set_size = kp->ki_rssize << PAGE_SHIFT;
+            reply->peak_working_set_size = kp->ki_rusage.ru_maxrss * 1024;
+            procstat_freeprocs( procstat, kp );
+        }
+        else ret = STATUS_ACCESS_DENIED;
+        procstat_close( procstat );
+    }
+    else ret = STATUS_ACCESS_DENIED;
+    return ret;
+}
+
+#endif /* HAVE_LIBPROCSTAT */
+


More information about the wine-devel mailing list