|
Packit |
ae235b |
/* Unit test for W32 version of g_poll()
|
|
Packit |
ae235b |
*
|
|
Packit |
ae235b |
* Copyright © 2017 Руслан Ижбулатов <lrn1986@gmail.com>
|
|
Packit |
ae235b |
*
|
|
Packit |
ae235b |
* This is free software; you can redistribute it and/or
|
|
Packit |
ae235b |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
ae235b |
* License as published by the Free Software Foundation; either
|
|
Packit |
ae235b |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
ae235b |
*
|
|
Packit |
ae235b |
* This is distributed in the hope that it will be useful,
|
|
Packit |
ae235b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
ae235b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
ae235b |
* Lesser General Public License for more details.
|
|
Packit |
ae235b |
*
|
|
Packit |
ae235b |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
ae235b |
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
ae235b |
*/
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
#include <glib.h>
|
|
Packit |
ae235b |
#include <Winsock2.h>
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
#define NUM_POLLEES 63
|
|
Packit |
ae235b |
#define NUM_POLLFDS 64
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
#define ASYNC_CONNECT_OK(r) (r == 0 || (r < 0 && GetLastError () == WSAEWOULDBLOCK))
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
#define REPEAT 1000
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
init_networking (void)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
WSADATA wsadata;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
|
|
Packit |
ae235b |
g_error ("Windows Sockets could not be initialized");
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
prepare_fds (SOCKET sockets[],
|
|
Packit |
ae235b |
GPollFD fds[],
|
|
Packit |
ae235b |
int num_pollees)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < num_pollees; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
fds[i].fd = (gintptr) WSACreateEvent ();
|
|
Packit |
ae235b |
g_assert (WSAEventSelect (sockets[i], (HANDLE) fds[i].fd, FD_READ | FD_CLOSE) == 0);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
reset_fds (GPollFD fds[],
|
|
Packit |
ae235b |
int num_pollees)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < num_pollees; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
WSAResetEvent ((HANDLE) fds[i].fd);
|
|
Packit |
ae235b |
fds[i].events = G_IO_IN | G_IO_OUT | G_IO_ERR;
|
|
Packit |
ae235b |
fds[i].revents = 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
reset_fds_msg (GPollFD fds[],
|
|
Packit |
ae235b |
int num_pollfds)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
fds[num_pollfds - 1].fd = G_WIN32_MSG_HANDLE;
|
|
Packit |
ae235b |
fds[num_pollfds - 1].events = G_IO_IN;
|
|
Packit |
ae235b |
fds[num_pollfds - 1].revents = 0;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
check_fds (SOCKET sockets[],
|
|
Packit |
ae235b |
GPollFD fds[],
|
|
Packit |
ae235b |
int num_pollees)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < num_pollees; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
if (fds[i].revents != 0)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
WSANETWORKEVENTS events;
|
|
Packit |
ae235b |
g_assert (WSAEnumNetworkEvents (sockets[i], 0, &events) == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
fds[i].revents = 0;
|
|
Packit |
ae235b |
if (events.lNetworkEvents & (FD_READ | FD_ACCEPT))
|
|
Packit |
ae235b |
fds[i].revents |= G_IO_IN;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (events.lNetworkEvents & FD_WRITE)
|
|
Packit |
ae235b |
fds[i].revents |= G_IO_OUT;
|
|
Packit |
ae235b |
else
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
/* We have called WSAEnumNetworkEvents() above but it didn't
|
|
Packit |
ae235b |
* set FD_WRITE.
|
|
Packit |
ae235b |
*/
|
|
Packit |
ae235b |
if (events.lNetworkEvents & FD_CONNECT)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
if (events.iErrorCode[FD_CONNECT_BIT] == 0)
|
|
Packit |
ae235b |
fds[i].revents |= G_IO_OUT;
|
|
Packit |
ae235b |
else
|
|
Packit |
ae235b |
fds[i].revents |= (G_IO_HUP | G_IO_ERR);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
if (fds[i].revents == 0 && (events.lNetworkEvents & (FD_CLOSE)))
|
|
Packit |
ae235b |
fds[i].revents |= G_IO_HUP;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
prepare_sockets (SOCKET sockets[],
|
|
Packit |
ae235b |
SOCKET opp_sockets[],
|
|
Packit |
ae235b |
GPollFD fds[],
|
|
Packit |
ae235b |
int num_pollees)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
SOCKET server;
|
|
Packit |
ae235b |
struct sockaddr_in sa;
|
|
Packit |
ae235b |
unsigned long ul = 1;
|
|
Packit |
ae235b |
int sa_size;
|
|
Packit |
ae235b |
int r;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
server = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
Packit |
ae235b |
g_assert (server != INVALID_SOCKET);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
memset(&sa, 0, sizeof sa);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
sa.sin_family = AF_INET;
|
|
Packit |
ae235b |
sa.sin_port = 0;
|
|
Packit |
ae235b |
sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
|
Packit |
ae235b |
sa_size = sizeof (sa);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_assert (bind (server, (const struct sockaddr *) &sa, sa_size) == 0);
|
|
Packit |
ae235b |
g_assert (getsockname (server, (struct sockaddr *) &sa, &sa_size) == 0);
|
|
Packit |
ae235b |
g_assert (listen (server, 1) == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < num_pollees; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
opp_sockets[i] = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
Packit |
ae235b |
g_assert (opp_sockets[i] != INVALID_SOCKET);
|
|
Packit |
ae235b |
g_assert (ioctlsocket (opp_sockets[i], FIONBIO, &ul) == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
r = connect (opp_sockets[i], (const struct sockaddr *) &sa, sizeof (sa));
|
|
Packit |
ae235b |
g_assert (ASYNC_CONNECT_OK (r));
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
sockets[i] = accept (server, NULL, NULL);
|
|
Packit |
ae235b |
g_assert (sockets[i] != INVALID_SOCKET);
|
|
Packit |
ae235b |
g_assert (ioctlsocket (sockets[i], FIONBIO, &ul) == 0);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
closesocket (server);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
cleanup_sockets (SOCKET sockets[],
|
|
Packit |
ae235b |
SOCKET opp_sockets[],
|
|
Packit |
ae235b |
int num_pollees)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < num_pollees; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
closesocket (sockets[i]);
|
|
Packit |
ae235b |
closesocket (opp_sockets[i]);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
bucketize (gint64 val,
|
|
Packit |
ae235b |
gint buckets[],
|
|
Packit |
ae235b |
gint64 bucket_limits[],
|
|
Packit |
ae235b |
gint count)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
if (val > bucket_limits[count - 1])
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
buckets[count - 1] += 1;
|
|
Packit |
ae235b |
return;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = count - 1; i > 0; i--)
|
|
Packit |
ae235b |
if (val < bucket_limits[i] && val >= bucket_limits[i - 1])
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
buckets[i] += 1;
|
|
Packit |
ae235b |
return;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
buckets[0] += 1;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
print_buckets (gint buckets[],
|
|
Packit |
ae235b |
gint64 bucket_limits[],
|
|
Packit |
ae235b |
gint count)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < count; i++)
|
|
Packit |
ae235b |
if (i < count - 1)
|
|
Packit |
ae235b |
g_print ("%-4lld-%4lld|", i == 0 ? 0 : bucket_limits[i - 1], bucket_limits[i] - 1);
|
|
Packit |
ae235b |
else
|
|
Packit |
ae235b |
g_print (" >= %-4lld|", bucket_limits[i - 1]);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_print ("\n");
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < count; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint len;
|
|
Packit |
ae235b |
gint padding;
|
|
Packit |
ae235b |
gint j;
|
|
Packit |
ae235b |
if (buckets[i] < 10)
|
|
Packit |
ae235b |
len = 1;
|
|
Packit |
ae235b |
else if (buckets[i] < 100)
|
|
Packit |
ae235b |
len = 2;
|
|
Packit |
ae235b |
else if (buckets[i] < 1000)
|
|
Packit |
ae235b |
len = 3;
|
|
Packit |
ae235b |
else
|
|
Packit |
ae235b |
len = 4;
|
|
Packit |
ae235b |
padding = 9 - len;
|
|
Packit |
ae235b |
for (j = 0; j < padding / 2; j++)
|
|
Packit |
ae235b |
g_print (" ");
|
|
Packit |
ae235b |
if (buckets[i] != 0)
|
|
Packit |
ae235b |
g_print ("%*d", len, buckets[i]);
|
|
Packit |
ae235b |
else
|
|
Packit |
ae235b |
g_print (" ");
|
|
Packit |
ae235b |
for (j = padding / 2; j < padding; j++)
|
|
Packit |
ae235b |
g_print (" ");
|
|
Packit |
ae235b |
g_print (" ");
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_print ("\n\n");
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
static void
|
|
Packit |
ae235b |
test_gpoll (void)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
SOCKET sockets[NUM_POLLEES];
|
|
Packit |
ae235b |
GPollFD fds[NUM_POLLFDS];
|
|
Packit |
ae235b |
SOCKET opp_sockets[NUM_POLLEES];
|
|
Packit |
ae235b |
gint i;
|
|
Packit |
ae235b |
gint activatable;
|
|
Packit |
ae235b |
gint64 times[REPEAT][2];
|
|
Packit |
ae235b |
#define BUCKET_COUNT 25
|
|
Packit |
ae235b |
gint64 bucket_limits[BUCKET_COUNT] = {3, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 120, 150, 180, 220, 280, 350, 450, 600, 800, 1000};
|
|
Packit |
ae235b |
gint buckets[BUCKET_COUNT];
|
|
Packit |
ae235b |
gint64 times_avg = 0, times_min = G_MAXINT64, times_max = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
prepare_sockets (sockets, opp_sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
prepare_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
activatable = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r, s, v, t;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
MSG msg;
|
|
Packit |
ae235b |
gboolean found_app;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
s = send (opp_sockets[activatable], (const char *) &t, 1, 0);
|
|
Packit |
ae235b |
g_assert (PostMessage (NULL, WM_APP, 1, 2));
|
|
Packit |
ae235b |
/* This is to ensure that all sockets catch up, otherwise some might not poll active */
|
|
Packit |
ae235b |
g_usleep (G_USEC_PER_SEC / 1000);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 1000);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
v = recv (sockets[activatable], (char *) &t, 1, 0);
|
|
Packit |
ae235b |
found_app = FALSE;
|
|
Packit |
ae235b |
while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
|
|
Packit |
ae235b |
if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
|
|
Packit |
ae235b |
found_app = TRUE;
|
|
Packit |
ae235b |
g_assert (s == 1);
|
|
Packit |
ae235b |
g_assert (r == 2);
|
|
Packit |
ae235b |
g_assert (v == 1);
|
|
Packit |
ae235b |
g_assert (found_app);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
activatable = (activatable + 1) % NUM_POLLEES;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
activatable = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r, s, v, t;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
s = send (opp_sockets[activatable], (const char *) &t, 1, 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_usleep (G_USEC_PER_SEC / 1000);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 1000);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
v = recv (sockets[activatable], (char *) &t, 1, 0);
|
|
Packit |
ae235b |
g_assert (s == 1);
|
|
Packit |
ae235b |
g_assert (r == 1);
|
|
Packit |
ae235b |
g_assert (v == 1);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
activatable = (activatable + 1) % NUM_POLLEES;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r, s, v, t;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
gint j;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
s = v = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (j = 0; j < NUM_POLLEES / 2; j++)
|
|
Packit |
ae235b |
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_usleep (G_USEC_PER_SEC / 1000);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 1000);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
for (j = 0; j < NUM_POLLEES / 2; j++)
|
|
Packit |
ae235b |
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
g_assert (s == NUM_POLLEES / 2);
|
|
Packit |
ae235b |
g_assert (r == NUM_POLLEES / 2);
|
|
Packit |
ae235b |
g_assert (v == NUM_POLLEES / 2);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r, s, v, t;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
gint j;
|
|
Packit |
ae235b |
MSG msg;
|
|
Packit |
ae235b |
gboolean found_app;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
s = v = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (j = 0; j < NUM_POLLEES / 2; j++)
|
|
Packit |
ae235b |
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
g_assert (PostMessage (NULL, WM_APP, 1, 2));
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
/* This is to ensure that all sockets catch up, otherwise some might not poll active */
|
|
Packit |
ae235b |
g_usleep (G_USEC_PER_SEC / 1000);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 1000);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
for (j = 0; j < NUM_POLLEES / 2; j++)
|
|
Packit |
ae235b |
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
found_app = FALSE;
|
|
Packit |
ae235b |
while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
|
|
Packit |
ae235b |
if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
|
|
Packit |
ae235b |
found_app = TRUE;
|
|
Packit |
ae235b |
g_assert (s == NUM_POLLEES / 2);
|
|
Packit |
ae235b |
g_assert (r == NUM_POLLEES / 2 + 1);
|
|
Packit |
ae235b |
g_assert (v == NUM_POLLEES / 2);
|
|
Packit |
ae235b |
g_assert (found_app);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r, s, v, t;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
gint j;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
s = v = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (j = 0; j < NUM_POLLEES; j++)
|
|
Packit |
ae235b |
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_usleep (G_USEC_PER_SEC / 1000);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 1000);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
for (j = 0; j < NUM_POLLEES; j++)
|
|
Packit |
ae235b |
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
g_assert (s == NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (v == NUM_POLLEES);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
activatable = 0;
|
|
Packit |
ae235b |
times_avg = 0;
|
|
Packit |
ae235b |
times_min = G_MAXINT64;
|
|
Packit |
ae235b |
times_max = 0;
|
|
Packit |
ae235b |
memset (buckets, 0, sizeof (gint) * BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (i = 0; i < REPEAT; i++)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
gint r, s, v, t;
|
|
Packit |
ae235b |
gint64 diff;
|
|
Packit |
ae235b |
gint j;
|
|
Packit |
ae235b |
MSG msg;
|
|
Packit |
ae235b |
gboolean found_app;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
s = v = 0;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
for (j = 0; j < activatable; j++)
|
|
Packit |
ae235b |
s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
g_assert (PostMessage (NULL, WM_APP, 1, 2));
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_usleep (G_USEC_PER_SEC / 1000);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times[i][0] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 1000);
|
|
Packit |
ae235b |
times[i][1] = g_get_monotonic_time ();
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
for (j = 0; j < activatable; j++)
|
|
Packit |
ae235b |
v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0;
|
|
Packit |
ae235b |
found_app = FALSE;
|
|
Packit |
ae235b |
while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
|
|
Packit |
ae235b |
if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2)
|
|
Packit |
ae235b |
found_app = TRUE;
|
|
Packit |
ae235b |
g_assert (s == activatable);
|
|
Packit |
ae235b |
g_assert (r == activatable + 1);
|
|
Packit |
ae235b |
g_assert (v == activatable);
|
|
Packit |
ae235b |
g_assert (found_app);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
reset_fds (fds, NUM_POLLEES);
|
|
Packit |
ae235b |
reset_fds_msg (fds, NUM_POLLFDS);
|
|
Packit |
ae235b |
r = g_poll (fds, NUM_POLLFDS, 0);
|
|
Packit |
ae235b |
check_fds (sockets, fds, NUM_POLLEES);
|
|
Packit |
ae235b |
g_assert (r == 0);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
diff = times[i][1] - times[i][0];
|
|
Packit |
ae235b |
if (times_min > diff)
|
|
Packit |
ae235b |
times_min = diff;
|
|
Packit |
ae235b |
if (times_max < diff)
|
|
Packit |
ae235b |
times_max = diff;
|
|
Packit |
ae235b |
times_avg += diff;
|
|
Packit |
ae235b |
bucketize (diff, buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
activatable = (activatable + 1) % NUM_POLLEES;
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
times_avg /= NUM_POLLEES;
|
|
Packit |
ae235b |
g_print ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
|
|
Packit |
ae235b |
print_buckets (buckets, bucket_limits, BUCKET_COUNT);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
cleanup_sockets (sockets, opp_sockets, NUM_POLLEES);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
int
|
|
Packit |
ae235b |
main (int argc,
|
|
Packit |
ae235b |
char *argv[])
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
int result;
|
|
Packit |
ae235b |
GMainContext *ctx;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_test_init (&argc, &argv, NULL);
|
|
Packit |
ae235b |
init_networking ();
|
|
Packit |
ae235b |
ctx = g_main_context_new ();
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_test_add_func ("/gpoll/gpoll", test_gpoll);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
result = g_test_run ();
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_main_context_unref (ctx);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
return result;
|
|
Packit |
ae235b |
}
|