/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

/*
** File:        thruput.c
** Description: Test server's throughput capability comparing various
**              implmentation strategies.
**
** Note:        Requires a server machine and an aribitrary number of
**              clients to bang on it. Trust the numbers on the server
**              more than those being displayed by the various clients.
*/

#include "prerror.h"
#include "prinrval.h"
#include "prinit.h"
#include "prio.h"
#include "prlock.h"
#include "prmem.h"
#include "prnetdb.h"
#include "prprf.h"
#include "prthread.h"
#include "pprio.h"
#include "plerror.h"
#include "plgetopt.h"

#define ADDR_BUFFER 100
#define PORT_NUMBER 51877
#define SAMPLING_INTERVAL 10
#define BUFFER_SIZE (32 * 1024)

static PRInt32 domain = PR_AF_INET;
static PRInt32 protocol = 6;  /* TCP */
static PRFileDesc *err = NULL;
static PRIntn concurrency = 1;
static PRInt32 xport_buffer = -1;
static PRUint32 initial_streams = 1;
static PRInt32 buffer_size = BUFFER_SIZE;
static PRThreadScope thread_scope = PR_LOCAL_THREAD;

typedef struct Shared
{
    PRLock *ml;
    PRUint32 sampled;
    PRUint32 threads;
    PRIntervalTime timein;
    PRNetAddr server_address;
} Shared;

static Shared *shared = NULL;

static PRStatus PrintAddress(const PRNetAddr* address)
{
    char buffer[ADDR_BUFFER];
    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
    if (PR_SUCCESS == rv)
        PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port));
    else PL_FPrintError(err, "PR_NetAddrToString");
    return rv;
}  /* PrintAddress */


static void PR_CALLBACK Clientel(void *arg)
{
    PRStatus rv;
    PRFileDesc *xport;
    PRInt32 bytes, sampled;
    PRIntervalTime now, interval;
    PRBool do_display = PR_FALSE;
    Shared *shared = (Shared*)arg;
    char *buffer = (char*)PR_Malloc(buffer_size);
    PRNetAddr *server_address = &shared->server_address;
    PRIntervalTime connect_timeout = PR_SecondsToInterval(5);
    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);

    PR_fprintf(err, "Client connecting to ");
    (void)PrintAddress(server_address);

    do
    {
        xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
        if (NULL == xport)
        {
            PL_FPrintError(err, "PR_Socket");
            return;
        }

        if (xport_buffer != -1)
        {
            PRSocketOptionData data;
            data.option = PR_SockOpt_RecvBufferSize;
            data.value.recv_buffer_size = (PRSize)xport_buffer;
            rv = PR_SetSocketOption(xport, &data);
            if (PR_FAILURE == rv)
                PL_FPrintError(err, "PR_SetSocketOption - ignored");
            data.option = PR_SockOpt_SendBufferSize;
            data.value.send_buffer_size = (PRSize)xport_buffer;
            rv = PR_SetSocketOption(xport, &data);
            if (PR_FAILURE == rv)
                PL_FPrintError(err, "PR_SetSocketOption - ignored");
        }

        rv = PR_Connect(xport, server_address, connect_timeout);
        if (PR_FAILURE == rv)
        {
            PL_FPrintError(err, "PR_Connect");
            if (PR_IO_TIMEOUT_ERROR != PR_GetError())
                PR_Sleep(connect_timeout);
            PR_Close(xport);  /* delete it and start over */
        }
    } while (PR_FAILURE == rv);

    do
    {
        bytes = PR_Recv(
            xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
        PR_Lock(shared->ml);
        now = PR_IntervalNow();
        shared->sampled += bytes;
        interval = now - shared->timein;
        if (interval > sampling_interval)
        {
            sampled = shared->sampled;
            shared->timein = now;
            shared->sampled = 0;
            do_display = PR_TRUE;
        }
        PR_Unlock(shared->ml);

        if (do_display)
        {
            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
            do_display = PR_FALSE;
        }

    } while (bytes > 0);
}  /* Clientel */

static void Client(const char *server_name)
{
    PRStatus rv;
    PRHostEnt host;
    char buffer[PR_NETDB_BUF_SIZE];
    PRIntervalTime dally = PR_SecondsToInterval(60);
    PR_fprintf(err, "Translating the name %s\n", server_name);
    rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host);
    if (PR_FAILURE == rv)
        PL_FPrintError(err, "PR_GetHostByName");
    else
    {
        if (PR_EnumerateHostEnt(
            0, &host, PORT_NUMBER, &shared->server_address) < 0)
            PL_FPrintError(err, "PR_EnumerateHostEnt");
        else
        {
            do
            {
                shared->threads += 1;
                (void)PR_CreateThread(
                    PR_USER_THREAD, Clientel, shared,
                    PR_PRIORITY_NORMAL, thread_scope,
                    PR_UNJOINABLE_THREAD, 8 * 1024);
                if (shared->threads == initial_streams)
                {
                    PR_Sleep(dally);
                    initial_streams += 1;
                }
            } while (PR_TRUE);
        }
    }
}

static void PR_CALLBACK Servette(void *arg)
{
    PRInt32 bytes, sampled;
    PRIntervalTime now, interval;
    PRBool do_display = PR_FALSE;
    PRFileDesc *client = (PRFileDesc*)arg;
    char *buffer = (char*)PR_Malloc(buffer_size);
    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);

    if (xport_buffer != -1)
    {
        PRStatus rv;
        PRSocketOptionData data;
        data.option = PR_SockOpt_RecvBufferSize;
        data.value.recv_buffer_size = (PRSize)xport_buffer;
        rv = PR_SetSocketOption(client, &data);
        if (PR_FAILURE == rv)
            PL_FPrintError(err, "PR_SetSocketOption - ignored");
        data.option = PR_SockOpt_SendBufferSize;
        data.value.send_buffer_size = (PRSize)xport_buffer;
        rv = PR_SetSocketOption(client, &data);
        if (PR_FAILURE == rv)
            PL_FPrintError(err, "PR_SetSocketOption - ignored");
    }

    do
    {
        bytes = PR_Send(
            client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);

        PR_Lock(shared->ml);
        now = PR_IntervalNow();
        shared->sampled += bytes;
        interval = now - shared->timein;
        if (interval > sampling_interval)
        {
            sampled = shared->sampled;
            shared->timein = now;
            shared->sampled = 0;
            do_display = PR_TRUE;
        }
        PR_Unlock(shared->ml);

        if (do_display)
        {
            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
            do_display = PR_FALSE;
        }
    } while (bytes > 0);
}  /* Servette */

static void Server(void)
{
    PRStatus rv;
    PRNetAddr server_address, client_address;
    PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);

    if (NULL == xport)
    {
        PL_FPrintError(err, "PR_Socket");
        return;
    }

    rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address);
    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr");
    else
    {
        rv = PR_Bind(xport, &server_address);
        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind");
        else
        {
            PRFileDesc *client;
            rv = PR_Listen(xport, 10);
            PR_fprintf(err, "Server listening on ");
            (void)PrintAddress(&server_address);
            do
            {
                client = PR_Accept(
                    xport, &client_address, PR_INTERVAL_NO_TIMEOUT);
                if (NULL == client) PL_FPrintError(err, "PR_Accept");
                else
                {
                    PR_fprintf(err, "Server accepting from ");
                    (void)PrintAddress(&client_address);
                    shared->threads += 1;
                    (void)PR_CreateThread(
                        PR_USER_THREAD, Servette, client,
                        PR_PRIORITY_NORMAL, thread_scope,
                        PR_UNJOINABLE_THREAD, 8 * 1024);
                }
            } while (PR_TRUE);

        }
    }
}  /* Server */

static void Help(void)
{
    PR_fprintf(err, "Usage: [-h] [<server>]\n");
    PR_fprintf(err, "\t-s <n>   Initial # of connections        (default: 1)\n");
    PR_fprintf(err, "\t-C <n>   Set 'concurrency'               (default: 1)\n");
    PR_fprintf(err, "\t-b <nK>  Client buffer size              (default: 32k)\n");
    PR_fprintf(err, "\t-B <nK>  Transport recv/send buffer size (default: sys)\n");
    PR_fprintf(err, "\t-G       Use GLOBAL threads              (default: LOCAL)\n");
    PR_fprintf(err, "\t-X       Use XTP transport               (default: TCP)\n");
    PR_fprintf(err, "\t-6       Use IPv6                        (default: IPv4)\n");
    PR_fprintf(err, "\t-h       This message and nothing else\n");
    PR_fprintf(err, "\t<server> DNS name of server\n");
    PR_fprintf(err, "\t\tIf <server> is not specified, this host will be\n");
    PR_fprintf(err, "\t\tthe server and not act as a client.\n");
}  /* Help */

int main(int argc, char **argv)
{
    PLOptStatus os;
    const char *server_name = NULL;
    PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:");

    err = PR_GetSpecialFD(PR_StandardError);

    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 0:  /* Name of server */
            server_name = opt->value;
            break;
        case 'G':  /* Globular threads */
            thread_scope = PR_GLOBAL_THREAD;
            break;
        case 'X':  /* Use XTP as the transport */
            protocol = 36;
            break;
        case '6':  /* Use IPv6 */
            domain = PR_AF_INET6;
            break;
        case 's':  /* initial_streams */
            initial_streams = atoi(opt->value);
            break;
        case 'C':  /* concurrency */
            concurrency = atoi(opt->value);
            break;
        case 'b':  /* buffer size */
            buffer_size = 1024 * atoi(opt->value);
            break;
        case 'B':  /* buffer size */
            xport_buffer = 1024 * atoi(opt->value);
            break;
        case 'h':  /* user wants some guidance */
        default:
            Help();  /* so give him an earful */
            return 2;  /* but not a lot else */
        }
    }
    PL_DestroyOptState(opt);

    shared = PR_NEWZAP(Shared);
    shared->ml = PR_NewLock();

    PR_fprintf(err,
        "This machine is %s\n",
        (NULL == server_name) ? "the SERVER" : "a CLIENT");

    PR_fprintf(err,
        "Transport being used is %s\n",
        (6 == protocol) ? "TCP" : "XTP");

    if (PR_GLOBAL_THREAD == thread_scope)
    {
        if (1 != concurrency)
        {
            PR_fprintf(err, "  **Concurrency > 1 and GLOBAL threads!?!?\n");
            PR_fprintf(err, "  **Ignoring concurrency\n");
            concurrency = 1;
        }
    }

    if (1 != concurrency)
    {
        PR_SetConcurrency(concurrency);
        PR_fprintf(err, "Concurrency set to %u\n", concurrency);
    }

    PR_fprintf(err,
        "All threads will be %s\n",
        (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");

    PR_fprintf(err, "Client buffer size will be %u\n", buffer_size);
   
    if (-1 != xport_buffer)
    PR_fprintf(
        err, "Transport send & receive buffer size will be %u\n", xport_buffer);
    

    if (NULL == server_name) Server();
    else Client(server_name);

}  /* main */

/* thruput.c */

