DESCRIPTION
===========

The userver is a micro web server that is meant to be used to experiment
with the design and implementation of web servers.

It was derived from several different servers that were originally
written by Abhishek Chandra and David Mosberger.

  Scalability of Linux Event-Dispatch Mechanisms 
  Abhishek Chandra and David Mosberger,
  Proceedings of the 2001 USENIX Annual Technical Conference, June 2001. 

In particular the original intention with userver was to permit
experimental comparisons of different event dispatch mechanisms within
the same application framework.  For this reason there are lots and lots
and lots of parameters. They are mainly used to control the behaviour
of the server.

Some of the design philosophy and experimental results obtained using
this server are described in:

  Exploring the Performance of Select-based Internet Servers 
  Tim Brecht and Michal Ostrowski, 
  HP Labs Technical Report HPL-2001-314, November, 2001. 

Much of the design and code is being developed to experiment with
a new Scalable Event Notification and Delivery Mechanism (SEND)
for Linux, which was originally developed by Michal Ostrorwski.

  A Mechanism for Scalable Event Notification and Delivery in Linux, 
  Michal Ostrowski, M.Math Thesis, 
  Department of Computer Science, University of Waterloo, November, 2000. 

An additional design decision of note is that all data structures are
allocated at initialization and are not resized (grown).  This helps
to ensure that experiments can be repeated because with dynamic sizing
of data structures different loads could result in different server
behaviour.

This micro web server is not meant to be a full-blown web server.
It is specifically designed for conducting performance experiments.
For that reason design decisions were made in favour of producing
repeatable experiments.

For more information see the man page (% make man) and view
either userver.txt userver.ps or userver.pdf and/or the documents
described above.

SOME FEATURES
=============

 o Event / Finite state machine based/driven
 o Reasonable small, simple, modifiable, fast, expandable
 o Support for a variety of event mechanisms 
    (e.g., select, poll, epoll, SEND, SIGIO)
 o Supports mmap, madvise, mlock for cached files
 o Supports write, writev, sendfile, TCP_CORK/UNCORK
 o Built in ability to explore a large variety of server implementation
   options
 o Extensive debugging and tracing facilities.
 o Extensive performance related statistics

CONTAINS CODE TO USE THE FOLLOWING EVENT MECHANISMS:
====================================================
 o select
 o poll
 o epoll 
   - requires recent versions of Linux)
 o SEND (Scalable Event Notification and Deliver)
   - requires kernel patches (currently available for 2.4.19 on x86.
 o SIGIO/signals (hasn't been tested in a long time)

 o Hope to add support for Linux (aio)

To add a new event mechanism:

 - You need to be able to tell the system which fds you are interested in
   (declare interest).
     [see interest_set.h interest_set.c]
 - You need to be able to enable and disable the notification of
   new connections
     [this is done using the interest set routines that get called
      via do_socket_new_conn_on and do_socket_new_conn_off]
   By default you probably shouldn't need to do anything here.
 - You need to be able to determine which new events have occurred and 
   process/handle them.  See:
      process_sds.c                 (for select-based events)
      process_poll_events.c         (for poll-based events)
      process_epoll_events.c        (for epoll-based events)
      send_handler.c and
      send_handler_array.c          (for SEND-based events)
      sigstuff.c : sigio_handler()  (for SIGIO-based connection request)

   Some of the existing code uses the routines:
      int event_set_is_readable_or_writable(int sd);
      int event_set_is_readable(int sd);
      int event_set_is_writable(int sd);
   [Note: the interest set is used to let the system know which events
    one is interested in and the event set is used to let the application
    know which of the events of interest occurred.]   


COMPILING
=========

Needs/requires gnu make.

It has been compiled and tested under IA32 Linux.
It has been compiled and only likghtly tested on IA64 Linux.
This has been compiled and only lightly run (not tested) on HP-UX (PA-RISC).
This has been compiled and only lightly run (not tested) on Solaris.

gcc was used on all of these platforms except HP-UX.

To get maximum performance ensure that NDEBUG is defined (see Makefile.base).
I believe that this will also turn debugging and tracing off.

To turn on/off debugging see debug.h (when NDEBUG is not defined).
To turn on/off tracing see   trace.h (when NDEBUG is not defined).

There are some problems with make depend.

To compile a new version from scratch (or after make vclean)
you may need to do:

  # Figure out if you want debugging and/or tracing on or off
	# edit debug.h and trace.h

  % make userver-depend
  % make userver

Or for the SEND based version
  % make userver-send-depend
  % make userver-send



Instructions for compiling for use with the SEND kernel.

You need a copy of the Scalable Event Notification and Delivery
(SEND) Linux Kernel mods.
% ln -s <where-ever-send-kernel-lives> ~/linux

  # Figure out if you want debugging and/or tracing on or off
	# edit debug.h and trace.h

  % make vclean
  % make userver-send-depend
  % make userver-send

An example set of options for running the userver using the SEND interface:
  ./userver-send -E -U -Y -m 0 -c 10 -f 20 -D 0xffffffff -K 0xffffffff


RUNNING
=======

It is probably best to read the HP Technical Report to figure out
how different parameters impact performance but a very server
can be run by just running userver.

% ./userver

Note that by default it listens on port 6800.

THE SOURCE
==========

Some code was written by people who use emacs and some code was written
by people who use vi. As a result the code can sometimes appear to be
incorrectly formated.

For vi I think that most of the code will look fine if you use:
:set ts=8
:set sw=2

I'm not sure with emacs.

I'm hoping to try to fix this up in future releases.

FOR MORE INFORMATION
====================
http://www.hpl.hp.com/research/linux/userver

