Re: pgbench bug / limitation

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: pgbench bug / limitation
Дата
Msg-id 1510961.1591380652@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: pgbench bug / limitation  (Andres Freund <andres@anarazel.de>)
Ответы Re: pgbench bug / limitation  (Fabien COELHO <coelho@cri.ensmp.fr>)
Re: pgbench bug / limitation  (David Rowley <dgrowleyml@gmail.com>)
Список pgsql-bugs
Andres Freund <andres@anarazel.de> writes:
> I'm fairly sure one can easily scale to large numbers of sockets on
> windows by using completion based APIs, but that doesn't seem like a
> realistic thing to use for pgbench anytime soon.

Agreed.  Seems like the best answer is to get in bed with the Windows
representation of fd_set, since we cannot avoid knowing that it is
different from other platforms' versions.  I suggest that we might as
well get all the way in and dodge the FD_SETSIZE limitation altogether,
as per the attached utterly-untested draft patch.

A remaining problem with this is that in theory, repeatedly applying
socket_has_input() after the wait could also be O(N^2) (unless FD_ISSET
is way smarter than I suspect it is).  In practice, that's probably not
a huge problem since there would normally be only a few FDs in the
result fd_set.  Still, I'd rather see us get out from under select()
altogether on Windows ... but maybe they *don't* have a better API
anywhere.  In any case, this should be a good bit better than what we
have now.

            regards, tom lane

diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 08a5947a9e..e37f833879 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -27,10 +27,6 @@
  *
  */
 
-#ifdef WIN32
-#define FD_SETSIZE 1024            /* must set before winsock2.h is included */
-#endif
-
 #include "postgres_fe.h"
 
 #include <ctype.h>
@@ -51,7 +47,11 @@
 #include <poll.h>
 #endif
 #else                            /* no ppoll(), so use select() */
+#ifdef WIN32
+#define POLL_USING_WINDOWS_SELECT
+#else
 #define POLL_USING_SELECT
+#endif
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
@@ -108,6 +108,19 @@ typedef struct socket_set
 
 #endif                            /* POLL_USING_SELECT */
 
+#ifdef POLL_USING_WINDOWS_SELECT
+#define SOCKET_WAIT_METHOD "select"
+
+/*----------
+ * On Windows, fd_set is a struct that's effectively
+ *        u_int    fd_count;
+ *        SOCKET    fd_array[FLEXIBLE_ARRAY_MEMBER];
+ *----------
+ */
+typedef fd_set socket_set;
+
+#endif                            /* POLL_USING_WINDOWS_SELECT */
+
 /*
  * Multi-platform pthread implementations
  */
@@ -6740,6 +6753,70 @@ socket_has_input(socket_set *sa, int fd, int idx)
 
 #endif                            /* POLL_USING_SELECT */
 
+#ifdef POLL_USING_WINDOWS_SELECT
+
+static socket_set *
+alloc_socket_set(int count)
+{
+    socket_set *sa;
+
+    sa = (socket_set *) pg_malloc(offsetof(socket_set, fd_array) +
+                                  sizeof(SOCKET) * count);
+    sa->fd_count = 0;
+    return sa;
+}
+
+static void
+free_socket_set(socket_set *sa)
+{
+    pg_free(sa);
+}
+
+static void
+clear_socket_set(socket_set *sa)
+{
+    FD_ZERO(sa);
+}
+
+static void
+add_socket_to_set(socket_set *sa, int fd, int idx)
+{
+    /*
+     * We do not use FD_SET() here, first because it enforces a maximum array
+     * length of FD_SETSIZE which is not relevant, and second because it
+     * uselessly de-duplicates entries, requiring O(N^2) time to add N FDs to
+     * the set.
+     */
+    Assert(idx == sa->fd_count);
+    sa->fd_array[sa->fd_count++] = fd;
+}
+
+static int
+wait_on_socket_set(socket_set *sa, int64 usecs)
+{
+    if (usecs > 0)
+    {
+        struct timeval timeout;
+
+        timeout.tv_sec = usecs / 1000000;
+        timeout.tv_usec = usecs % 1000000;
+        /* Note that Windows ignores select's first argument */
+        return select(0, sa, NULL, NULL, &timeout);
+    }
+    else
+    {
+        return select(0, sa, NULL, NULL, NULL);
+    }
+}
+
+static bool
+socket_has_input(socket_set *sa, int fd, int idx)
+{
+    return (FD_ISSET(fd, sa) != 0);
+}
+
+#endif                            /* POLL_USING_WINDOWS_SELECT */
+
 
 /* partial pthread implementation for Windows */


В списке pgsql-bugs по дате отправления:

Предыдущее
От: Andres Freund
Дата:
Сообщение: Re: pgbench bug / limitation
Следующее
От: Fabien COELHO
Дата:
Сообщение: Re: pgbench bug / limitation