Blame src/examples/benchmark.c

Packit 875988
/*
Packit 875988
     This file is part of libmicrohttpd
Packit 875988
     Copyright (C) 2007, 2013 Christian Grothoff (and other contributing authors)
Packit 875988
Packit 875988
     This library is free software; you can redistribute it and/or
Packit 875988
     modify it under the terms of the GNU Lesser General Public
Packit 875988
     License as published by the Free Software Foundation; either
Packit 875988
     version 2.1 of the License, or (at your option) any later version.
Packit 875988
Packit 875988
     This library is distributed in the hope that it will be useful,
Packit 875988
     but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 875988
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 875988
     Lesser General Public License for more details.
Packit 875988
Packit 875988
     You should have received a copy of the GNU Lesser General Public
Packit 875988
     License along with this library; if not, write to the Free Software
Packit 875988
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 875988
*/
Packit 875988
/**
Packit 875988
 * @file benchmark.c
Packit 875988
 * @brief minimal code to benchmark MHD GET performance
Packit 875988
 * @author Christian Grothoff
Packit 875988
 */
Packit 875988
Packit 875988
#include "platform.h"
Packit 875988
#include <microhttpd.h>
Packit 875988
Packit 875988
#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
Packit 875988
#undef CPU_COUNT
Packit 875988
#endif
Packit 875988
#if !defined(CPU_COUNT)
Packit 875988
#define CPU_COUNT 2
Packit 875988
#endif
Packit 875988
Packit 875988
#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
Packit 875988
Packit 875988
Packit 875988
#define SMALL (1024 * 128)
Packit 875988
Packit 875988
/**
Packit 875988
 * Number of threads to run in the thread pool.  Should (roughly) match
Packit 875988
 * the number of cores on your system.
Packit 875988
 */
Packit 875988
#define NUMBER_OF_THREADS CPU_COUNT
Packit 875988
Packit 875988
static unsigned int small_deltas[SMALL];
Packit 875988
Packit 875988
static struct MHD_Response *response;
Packit 875988
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Signature of the callback used by MHD to notify the
Packit 875988
 * application about completed requests.
Packit 875988
 *
Packit 875988
 * @param cls client-defined closure
Packit 875988
 * @param connection connection handle
Packit 875988
 * @param con_cls value as set by the last call to
Packit 875988
 *        the MHD_AccessHandlerCallback
Packit 875988
 * @param toe reason for request termination
Packit 875988
 * @see MHD_OPTION_NOTIFY_COMPLETED
Packit 875988
 */
Packit 875988
static void
Packit 875988
completed_callback (void *cls,
Packit 875988
		    struct MHD_Connection *connection,
Packit 875988
		    void **con_cls,
Packit 875988
		    enum MHD_RequestTerminationCode toe)
Packit 875988
{
Packit 875988
  struct timeval *tv = *con_cls;
Packit 875988
  struct timeval tve;
Packit 875988
  uint64_t delta;
Packit 875988
  (void)cls;         /* Unused. Silent compiler warning. */
Packit 875988
  (void)connection;  /* Unused. Silent compiler warning. */
Packit 875988
  (void)toe;         /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  if (NULL == tv)
Packit 875988
    return;
Packit 875988
  gettimeofday (&tve, NULL);
Packit 875988
Packit 875988
  delta = 0;
Packit 875988
  if (tve.tv_usec >= tv->tv_usec)
Packit 875988
    delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
Packit 875988
      + (tve.tv_usec - tv->tv_usec);
Packit 875988
  else
Packit 875988
    delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
Packit 875988
      - tv->tv_usec + tve.tv_usec;
Packit 875988
  if (delta < SMALL)
Packit 875988
    small_deltas[delta]++;
Packit 875988
  else
Packit 875988
    fprintf (stdout, "D: %llu 1\n", (unsigned long long) delta);
Packit 875988
  free (tv);
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
static void *
Packit 875988
uri_logger_cb (void *cls,
Packit 875988
	       const char *uri)
Packit 875988
{
Packit 875988
  struct timeval *tv = malloc (sizeof (struct timeval));
Packit 875988
  (void)cls; /* Unused. Silent compiler warning. */
Packit 875988
  (void)uri; /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  if (NULL != tv)
Packit 875988
    gettimeofday (tv, NULL);
Packit 875988
  return tv;
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
static int
Packit 875988
ahc_echo (void *cls,
Packit 875988
          struct MHD_Connection *connection,
Packit 875988
          const char *url,
Packit 875988
          const char *method,
Packit 875988
          const char *version,
Packit 875988
          const char *upload_data, size_t *upload_data_size, void **ptr)
Packit 875988
{
Packit 875988
  (void)cls;               /* Unused. Silent compiler warning. */
Packit 875988
  (void)url;               /* Unused. Silent compiler warning. */
Packit 875988
  (void)version;           /* Unused. Silent compiler warning. */
Packit 875988
  (void)upload_data;       /* Unused. Silent compiler warning. */
Packit 875988
  (void)upload_data_size;  /* Unused. Silent compiler warning. */
Packit 875988
  (void)ptr;               /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  if (0 != strcmp (method, "GET"))
Packit 875988
    return MHD_NO;              /* unexpected method */
Packit 875988
  return MHD_queue_response (connection, MHD_HTTP_OK, response);
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
int
Packit 875988
main (int argc, char *const *argv)
Packit 875988
{
Packit 875988
  struct MHD_Daemon *d;
Packit 875988
  unsigned int i;
Packit 875988
Packit 875988
  if (argc != 2)
Packit 875988
    {
Packit 875988
      printf ("%s PORT\n", argv[0]);
Packit 875988
      return 1;
Packit 875988
    }
Packit 875988
  response = MHD_create_response_from_buffer (strlen (PAGE),
Packit 875988
					      (void *) PAGE,
Packit 875988
					      MHD_RESPMEM_PERSISTENT);
Packit 875988
#if 0
Packit 875988
  (void) MHD_add_response_header (response,
Packit 875988
				  MHD_HTTP_HEADER_CONNECTION,
Packit 875988
				  "close");
Packit 875988
#endif
Packit 875988
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_SUPPRESS_DATE_NO_CLOCK
Packit 875988
#ifdef EPOLL_SUPPORT
Packit 875988
			| MHD_USE_EPOLL | MHD_USE_TURBO
Packit 875988
#endif
Packit 875988
			,
Packit 875988
                        atoi (argv[1]),
Packit 875988
                        NULL, NULL, &ahc_echo, NULL,
Packit 875988
			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
Packit 875988
			MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
Packit 875988
			MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
Packit 875988
			MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
Packit 875988
			MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
Packit 875988
			MHD_OPTION_END);
Packit 875988
  if (d == NULL)
Packit 875988
    return 1;
Packit 875988
  (void) getc (stdin);
Packit 875988
  MHD_stop_daemon (d);
Packit 875988
  MHD_destroy_response (response);
Packit 875988
  for (i=0;i
Packit 875988
    if (0 != small_deltas[i])
Packit 875988
      fprintf (stdout, "D: %d %u\n", i, small_deltas[i]);
Packit 875988
  return 0;
Packit 875988
}