getrusage-windows: getrusage() for Windows.
authorGurucharan Shetty <gshetty@nicira.com>
Thu, 6 Mar 2014 20:55:53 +0000 (12:55 -0800)
committerGurucharan Shetty <gshetty@nicira.com>
Fri, 7 Mar 2014 00:35:04 +0000 (16:35 -0800)
We use getrusage mainly to get user CPU time and system CPU time.
Windows has a GetProcessTimes and GetThreadTimes that does the
same job. So use them.

We also use getrusage to get page faults. Use GetProcessMemoryInfo()
for that.

We also get number of context switches, block i/o times and use it for
debug information when we wake up from poll_block late. I haven't found
functions for that in Windows. We only use it for debug information, so
it should be okay not implementing it.

Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Co-authored-by: Linda Sun <lsun@vmware.com>
Signed-off-by: Linda Sun <lsun@vmware.com>
Acked-by: Ben Pfaff <blp@nicira.com>
include/windows/automake.mk
include/windows/sys/resource.h [new file with mode: 0644]
lib/automake.mk
lib/getrusage-windows.c [new file with mode: 0644]

index 2771270..b8f144e 100644 (file)
@@ -8,4 +8,5 @@
 noinst_HEADERS += \
        include/windows/getopt.h \
        include/windows/syslog.h \
+       include/windows/sys/resource.h \
        include/windows/windefs.h
diff --git a/include/windows/sys/resource.h b/include/windows/sys/resource.h
new file mode 100644 (file)
index 0000000..d4628f2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SYS_RESOURCE_H
+#define SYS_RESOURCE_H 1
+
+struct rusage {
+    struct timeval ru_utime; /* user CPU time used */
+    struct timeval ru_stime; /* system CPU time used */
+    long   ru_maxrss;        /* maximum resident set size */
+    long   ru_ixrss;         /* integral shared memory size */
+    long   ru_idrss;         /* integral unshared data size */
+    long   ru_isrss;         /* integral unshared stack size */
+    long   ru_minflt;        /* page reclaims (soft page faults) */
+    long   ru_majflt;        /* page faults (hard page faults) */
+    long   ru_nswap;         /* swaps */
+    long   ru_inblock;       /* block input operations */
+    long   ru_oublock;       /* block output operations */
+    long   ru_msgsnd;        /* IPC messages sent */
+    long   ru_msgrcv;        /* IPC messages received */
+    long   ru_nsignals;      /* signals received */
+    long   ru_nvcsw;         /* voluntary context switches */
+    long   ru_nivcsw;        /* involuntary context switches */
+};
+
+#ifndef RUSAGE_SELF
+#define RUSAGE_SELF 1
+#endif
+
+#ifndef RUSAGE_CHILDREN
+#define RUSAGE_CHILDREN 2
+#endif
+
+#ifndef RUSAGE_THREAD
+#define RUSAGE_THREAD 3
+#endif
+
+#endif /* sys/resource.h */
index 476421c..b1688ef 100644 (file)
@@ -236,6 +236,7 @@ if WIN32
 lib_libopenvswitch_la_SOURCES += \
        lib/daemon-windows.c \
        lib/getopt_long.c \
+       lib/getrusage-windows.c \
        lib/latch-windows.c \
        lib/stream-fd-windows.c
 else
diff --git a/lib/getrusage-windows.c b/lib/getrusage-windows.c
new file mode 100644 (file)
index 0000000..0282a17
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <psapi.h>
+#include <sys/resource.h>
+#include <time.h>
+#include "util.h"
+#include "vlog.h"
+
+VLOG_DEFINE_THIS_MODULE(getrusage_windows);
+
+static void
+usage_to_timeval(FILETIME *ft, struct timeval *tv)
+{
+    ULARGE_INTEGER time;
+    time.LowPart = ft->dwLowDateTime;
+    time.HighPart = ft->dwHighDateTime;
+
+    tv->tv_sec = time.QuadPart / 10000000;
+    tv->tv_usec = (time.QuadPart % 10000000) / 10;
+}
+
+int
+getrusage(int who, struct rusage *usage)
+{
+    FILETIME creation_time, exit_time, kernel_time, user_time;
+    PROCESS_MEMORY_COUNTERS pmc;
+
+    memset(usage, 0, sizeof(struct rusage));
+
+    if (who == RUSAGE_SELF) {
+        if (!GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
+                             &kernel_time, &user_time)) {
+            VLOG_ERR("failed at GetProcessTimes: %s",
+                      ovs_lasterror_to_string());
+            return -1;
+        }
+
+        if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
+            VLOG_ERR("failed at GetProcessMemoryInfo: %s",
+                      ovs_lasterror_to_string());
+            return -1;
+        }
+
+        usage_to_timeval(&kernel_time, &usage->ru_stime);
+        usage_to_timeval(&user_time, &usage->ru_utime);
+        usage->ru_majflt = pmc.PageFaultCount;
+        usage->ru_maxrss = pmc.PeakWorkingSetSize / 1024;
+        return 0;
+    } else if (who == RUSAGE_THREAD) {
+        if (!GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time,
+                            &kernel_time, &user_time)) {
+            VLOG_ERR("failed at GetThreadTimes: %s",
+                      ovs_lasterror_to_string());
+            return -1;
+        }
+        usage_to_timeval(&kernel_time, &usage->ru_stime);
+        usage_to_timeval(&user_time, &usage->ru_utime);
+        return 0;
+    } else {
+        return -1;
+    }
+}