[sysprof] capture: add some portability fallbacks



commit ac1767eff234e3960d902aed626d7f3b78623bee
Author: Christian Hergert <chergert redhat com>
Date:   Mon May 6 20:04:17 2019 -0700

    capture: add some portability fallbacks
    
    If we're on non-Linux, we can use some portability fallbacks to
    get similar behavior to Linux. I'm sure we can optimize this a
    bit more for FreeBSD if someone with that installed wants to
    come look at things and improve them.

 lib/capture/sp-capture-util-private.h |  93 +++++-----------
 lib/capture/sp-capture-util.c         | 193 ++++++++++++++++++++++++++++++++++
 2 files changed, 217 insertions(+), 69 deletions(-)
---
diff --git a/lib/capture/sp-capture-util-private.h b/lib/capture/sp-capture-util-private.h
index bc96fe3..9bf8669 100644
--- a/lib/capture/sp-capture-util-private.h
+++ b/lib/capture/sp-capture-util-private.h
@@ -24,79 +24,34 @@
 #ifdef __linux__
 # include <sys/sendfile.h>
 #endif
-#include <errno.h>
+
 #include <unistd.h>
 
 #ifdef __linux__
-# define _sp_sendfile sendfile
+# define _sp_getpagesize getpagesize
+# define _sp_pread       pread
+# define _sp_pwrite      pwrite
+# define _sp_write       write
+# define _sp_getpid      getpid
+# define _sp_sendfile    sendfile
 #else
-static inline ssize_t
-_sp_sendfile (int     out_fd,
-              int     in_fd,
-              off_t  *offset,
-              size_t  count)
-{
-  ssize_t total = 0;
-  off_t wpos = 0;
-  off_t rpos = 0;
-
-  errno = 0;
-
-  if (offset != NULL && *offset > 0)
-    wpos = rpos = *offset;
-
-  while (count > 0)
-    {
-      unsigned char buf[4096*4];
-      ssize_t n_written = 0;
-      ssize_t n_read;
-      off_t off = 0;
-      size_t to_read;
-
-      /* Try to page align */
-      if ((rpos % 4096) != 0)
-        to_read = 4096 - rpos;
-      else
-        to_read = sizeof buf;
-
-      if (to_read > count)
-        to_read = count;
-
-      errno = 0;
-      n_read = pread (in_fd, buf, to_read, rpos);
-
-      if (n_read <= 0)
-        return -1;
-
-      g_assert (count >= n_read);
-
-      count -= n_read;
-      rpos += n_read;
-
-      while (wpos < rpos)
-        {
-          g_assert (off < sizeof buf);
-
-          errno = 0;
-          n_written = write (out_fd, &buf[off], rpos - wpos);
-
-          if (n_written <= 0)
-            return -1;
-
-          wpos += n_written;
-          off += n_written;
-          total += n_written;
-        }
-    }
-
-  g_assert (count == 0);
-
-  if (offset != NULL)
-    *offset = rpos;
-
-  errno = 0;
-  return total;
-}
+size_t  _sp_getpagesize (void);
+ssize_t _sp_pread       (int     fd,
+                         void   *buf,
+                         size_t  count,
+                         off_t   offset);
+ssize_t _sp_pwrite      (int         fd,
+                         const void *buf,
+                         size_t      count,
+                         off_t       offset);
+ssize_t _sp_write       (int         fd,
+                         const void *buf,
+                         size_t      count);
+gint32  _sp_getpid      (void);
+ssize_t _sp_sendfile    (int     out_fd,
+                         int     in_fd,
+                         off_t  *offset,
+                         size_t  count);
 #endif
 
 #endif /* SP_CAPTURE_UTIL_PRIVATE_H */
diff --git a/lib/capture/sp-capture-util.c b/lib/capture/sp-capture-util.c
new file mode 100644
index 0000000..0c6a907
--- /dev/null
+++ b/lib/capture/sp-capture-util.c
@@ -0,0 +1,193 @@
+/* sp-capture-util.c
+ *
+ * Copyright © 2019 Christian Hergert <chergert redhat com>
+ *
+ * This file 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 of the License, or (at your option)
+ * any later version.
+ *
+ * This file 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 General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <glib.h>
+
+#ifdef G_OS_WIN32
+# include <process.h>
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "sp-capture-util-private.h"
+
+#ifdef G_OS_WIN32
+static G_LOCK_DEFINE (_sp_io_sync);
+#endif
+
+size_t
+_sp_getpagesize (void)
+{
+  static size_t pgsz = 0;
+
+  if G_UNLIKELY (pgsz == 0)
+    {
+#ifdef G_OS_WIN32
+      SYSTEM_INFO system_info;
+      GetSystemInfo (&system_info);
+      pgsz = system_info.dwPageSize;
+#else
+      pgsz = getpagesize ();
+#endif
+    }
+
+  return pgsz;
+}
+
+ssize_t
+_sp_pread (int     fd,
+           void   *buf,
+           size_t  count,
+           off_t   offset)
+{
+#ifdef G_OS_WIN32
+  ssize_t ret = -1;
+
+  G_LOCK (_sp_io_sync);
+  errno = 0;
+  if (lseek (fd, offset, SEEK_SET) != -1)
+    ret = read (fd, buf, count);
+  G_UNLOCK (_sp_io_sync);
+
+  return ret;
+#else
+  errno = 0;
+  return pread (fd, buf, count, offset);
+#endif
+}
+
+ssize_t
+_sp_pwrite (int         fd,
+            const void *buf,
+            size_t      count,
+            off_t       offset)
+{
+#ifdef G_OS_WIN32
+  ssize_t ret = -1;
+
+  G_LOCK (_sp_io_sync);
+  errno = 0;
+  if (lseek (fd, offset, SEEK_SET) != -1)
+    ret = write (fd, buf, count);
+  G_UNLOCK (_sp_io_sync);
+
+  return ret;
+#else
+  errno = 0;
+  return pwrite (fd, buf, count, offset);
+#endif
+}
+
+ssize_t
+_sp_write (int         fd,
+           const void *buf,
+           size_t      count)
+{
+#ifdef G_OS_WIN32
+  ssize_t ret = -1;
+
+  G_LOCK (_sp_io_sync);
+  errno = 0;
+  ret = write (fd, buf, count);
+  G_UNLOCK (_sp_io_sync);
+
+  return ret;
+#else
+  errno = 0;
+  return write (fd, buf, count);
+#endif
+}
+
+gint32
+_sp_getpid (void)
+{
+#ifdef G_OS_WIN32
+  return _getpid ();
+#else
+  return getpid ();
+#endif
+}
+
+ssize_t
+_sp_sendfile (int     out_fd,
+              int     in_fd,
+              off_t  *offset,
+              size_t  count)
+{
+  ssize_t total = 0;
+  off_t wpos = 0;
+  off_t rpos = 0;
+
+  errno = 0;
+
+  if (offset != NULL && *offset > 0)
+    wpos = rpos = *offset;
+
+  while (count > 0)
+    {
+      unsigned char buf[4096*4];
+      ssize_t n_written = 0;
+      ssize_t n_read;
+      off_t off = 0;
+      size_t to_read;
+
+      /* Try to page align */
+      if ((rpos % 4096) != 0)
+        to_read = 4096 - rpos;
+      else
+        to_read = sizeof buf;
+
+      if (to_read > count)
+        to_read = count;
+
+      errno = 0;
+      n_read = _sp_pread (in_fd, buf, to_read, rpos);
+
+      if (n_read <= 0)
+        return -1;
+
+      g_assert (count >= n_read);
+
+      count -= n_read;
+      rpos += n_read;
+
+      while (wpos < rpos)
+        {
+          g_assert (off < sizeof buf);
+
+          errno = 0;
+          n_written = write (out_fd, &buf[off], rpos - wpos);
+
+          if (n_written <= 0)
+            return -1;
+
+          wpos += n_written;
+          off += n_written;
+          total += n_written;
+        }
+    }
+
+  g_assert (count == 0);
+
+  if (offset != NULL)
+    *offset = rpos;
+
+  errno = 0;
+  return total;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]