diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:30 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:30 +0000 |
commit | c44379cc7d9c7aa113989237ab0f56db12aa5219 (patch) | |
tree | 66a84b20d47f2269d8bdc6e0323f338763424d3a /ACE/apps/JAWS/stress_testing | |
parent | 3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (diff) | |
download | ATCD-c44379cc7d9c7aa113989237ab0f56db12aa5219.tar.gz |
Repo restructuring
Diffstat (limited to 'ACE/apps/JAWS/stress_testing')
-rw-r--r-- | ACE/apps/JAWS/stress_testing/README | 54 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/benchd.cpp | 240 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/client.h | 8 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/config | 3 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/connection.cpp | 98 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/connection.h | 22 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/cp.cpp | 11 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/cp.h | 14 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/global.h | 31 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/http.h | 16 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/http_tester.cpp | 172 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/out | 2 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/stats.cpp | 88 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/stats.h | 31 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/util.cpp | 60 | ||||
-rw-r--r-- | ACE/apps/JAWS/stress_testing/util.h | 34 |
16 files changed, 884 insertions, 0 deletions
diff --git a/ACE/apps/JAWS/stress_testing/README b/ACE/apps/JAWS/stress_testing/README new file mode 100644 index 00000000000..0969522d638 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/README @@ -0,0 +1,54 @@ +http_tester +----------- + +This is the http_tester suite, an ACE based HTTP benchmarking tool, +used to evaluate the performance of JAWS and other HTTP servers. + +Usage +----- + +To use the http_tester, you need to use a config file "infile", which +consists of a list of experiments, one on each line. http_tester logs +output data in the "outfile". + +Usage: http_tester infile outfile + +Experiments +----------- + +Each experiment consists of several space-delimited compulsory +fields, as follows: + +experiment_id (string) +total_number_of_requests (integer) +request_rate (float) +url1 (first URL) +p1 (probability of requesting the first URL) +url2 (second URL) +p2 (probability of requesting the second URL) +url3 (third URL) +p3 (probability of requesting the third URL) +TCP_NODELAY (boolean, 1 == TCP_NODELAY is set) +SOCKET_RECV_BUFSIZ (usually 65536) + +URLS must be of the form: + +http://www.cs.wustl.edu:8888/~sumedh/index.html + +(the port number is required, im making it optional in the next version). + +Please see the sample file "config", for an example. + +Output file +----------- + +The output file consists of the following space delimited fields: + +Experiment Id (string) +Average throughput of connection (float) +Average latency of connection (float) +Maximum number of active connections at any given time (int) + + +Sumedh Mungee +<sumedh@cs.wustl.edu> diff --git a/ACE/apps/JAWS/stress_testing/benchd.cpp b/ACE/apps/JAWS/stress_testing/benchd.cpp new file mode 100644 index 00000000000..ff17f669430 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/benchd.cpp @@ -0,0 +1,240 @@ +// $Id$ + +// benchd: Adapted from the "ntalker" example. +// Sumedh Mungee + +#include "ace/Process.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram_Mcast.h" +#include "ace/Reactor.h" +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" + +ACE_RCSID(stress_testing, benchd, "$Id$") + +#if defined (ACE_HAS_IP_MULTICAST) +// network interface to subscribe to +// this is hardware specific. +// use netstat (1M) to find whether your interface +// is le0 or ie0 + +// Maximum number of arguments supported for a request +static const int MAX_ARGS = 16; +// Name of the client benchmarking tool +static const char *TESTER = "http_tester"; +static int QUIET = 0; +static const char *INTERFACE = "le0"; +static const char *MCAST_ADDR = ACE_DEFAULT_MULTICAST_ADDR; +static const u_short UDP_PORT = ACE_DEFAULT_MULTICAST_PORT; +static const char *OUTPUT_FILE_NAME = "benchd.log"; +static ACE_HANDLE OUTPUT_FILE; + +// Handle both multicast and stdin events. + +class Handle_Events : public ACE_Event_Handler +{ +public: + Handle_Events (u_short udp_port, + const char *ip_addr, + const char *interface, + ACE_Reactor &reactor); + ~Handle_Events (void); + + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + +private: + int serve (char *buf); + ACE_SOCK_Dgram_Mcast mcast_; + ACE_Handle_Set handle_set_; +}; + +int +Handle_Events::handle_input (ACE_HANDLE h) +{ + char buf[BUFSIZ]; + + if (h == 0) + { + int readresult = ACE_OS::read (h, buf, BUFSIZ); + if (readresult > 0) + { + if (this->mcast_.send (buf, readresult) != readresult) + { + ACE_OS::perror ("send error"); + return -1; + } + return 0; + } + else if (readresult == -1) + ::perror ("can't read from STDIN"); + + return -1; + } + else + { + ACE_INET_Addr remote_addr; + + // receive message from multicast group + int retcode = this->mcast_.recv (buf, sizeof buf, remote_addr); + + if (retcode != -1) + { + /* + cout << "received datagram from host " << remote_addr.get_host_name () + << " on port " << remote_addr.get_port_number () + << " bytes = " << retcode << endl; + */ + serve (buf); + return 0; + } + + ACE_OS::perror ("Something amiss."); + return -1; + } +} + +int +Handle_Events::handle_close (ACE_HANDLE h, ACE_Reactor_Mask) +{ + if (h == 0) + cout << "STDIN_Events handle removed from reactor." << endl << flush; + else + cout << "Mcast_Events handle removed from reactor." << endl << flush; + return 0; +} + +Handle_Events::~Handle_Events (void) +{ + // ACE_OS::exit on error (bogus)... + + if (this->mcast_.unsubscribe () == -1) + ACE_OS::perror ("unsubscribe fails"), ACE_OS::exit (1); +} + +Handle_Events::Handle_Events (u_short udp_port, + const char *ip_addr, + const char *interface, + ACE_Reactor &reactor) +{ + // Create multicast address to listen on. + + ACE_INET_Addr sockmc_addr (udp_port, ip_addr); + + // subscribe to multicast group. + + if (this->mcast_.subscribe (sockmc_addr, 1, interface) == -1) + ACE_OS::perror ("can't subscribe to multicast group"), ACE_OS::exit (1); + + // Disable loopbacks. + // if (this->mcast_.set_option (IP_MULTICAST_LOOP, 0) == -1 ) + // ACE_OS::perror (" can't disable loopbacks " ), ACE_OS::exit (1); + + if (!QUIET) { + this->handle_set_.set_bit (0); + } + this->handle_set_.set_bit (this->mcast_.get_handle ()); + + // Register callbacks with the ACE_Reactor. + if (reactor.register_handler (this->handle_set_, + this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_OS::perror ("can't register events"), ACE_OS::exit (1); +} + + +// This method handles multicast requests.. +// These requests are of the following form: +// command (arguments) + + +// currently only one is supported (and indeed needed :-)) http_tester +// arguments + +int +Handle_Events::serve (char *buf) +{ + ACE_ARGV arguments (buf); + + if (ACE_OS::strcmp (arguments[0], TESTER) == 0) + { + ACE_Process_Options po; + ACE_Process p; + + po.set_handles (ACE_INVALID_HANDLE, OUTPUT_FILE, OUTPUT_FILE); + po.command_line (arguments.argv ()); + + p.spawn (po); + return 0; + } + else + return -1; +} + +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "i:u:q"); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'q': + QUIET = 1; + case 'i': + INTERFACE = get_opt.opt_arg (); + break; + case 'u': + // Usage fallthrough. + default: + ACE_DEBUG ((LM_DEBUG, "%s -i interface\n", argv[0])); + ACE_OS::exit (1); + } +} + +static sig_atomic_t done = 0; + +// Signal handler. + +extern "C" void +handler (int) +{ + done = 1; +} + +int +main (int argc, char *argv[]) +{ + ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); + ACE_OS::signal (SIGCLD, SIG_IGN); + ACE_UNUSED_ARG (sa); + + parse_args (argc, argv); + + OUTPUT_FILE = ACE_OS::open (OUTPUT_FILE_NAME, O_CREAT | O_WRONLY, 0644); + if (OUTPUT_FILE == 0) + return 1; + + ACE_Reactor reactor; + Handle_Events handle_events (UDP_PORT, MCAST_ADDR, INTERFACE, reactor); + + // main loop + + while (!done) + reactor.handle_events (); + + ACE_OS::close (OUTPUT_FILE); + cout << "\nbenchd done.\n"; + return 0; +} +#else +int +main (int argc, char *argv[]) +{ + ACE_ERROR ((LM_ERROR, "error: %s must be run on a platform that support IP multicast\n", + argv[0])); + return 0; +} +#endif /* ACE_HAS_IP_MULTICAST */ diff --git a/ACE/apps/JAWS/stress_testing/client.h b/ACE/apps/JAWS/stress_testing/client.h new file mode 100644 index 00000000000..58ef98c7bdf --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/client.h @@ -0,0 +1,8 @@ +// $Id$ + +#include "global.h" +#include "util.h" +#include "http.h" +#include "cp.h" +#include "stats.h" + diff --git a/ACE/apps/JAWS/stress_testing/config b/ACE/apps/JAWS/stress_testing/config new file mode 100644 index 00000000000..7e730eaef10 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/config @@ -0,0 +1,3 @@ +1.0 1 1 http://localhost:5432/IO.h 1 a 0 b 0 1 65536 +2.0 1 1 http://localhost:5432/IO.h 1 a 0 b 0 1 65536 + diff --git a/ACE/apps/JAWS/stress_testing/connection.cpp b/ACE/apps/JAWS/stress_testing/connection.cpp new file mode 100644 index 00000000000..a243fdd01d5 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/connection.cpp @@ -0,0 +1,98 @@ +// $Id$ + +#include "connection.h" + +ACE_RCSID(stress_testing, connection, "$Id$") + +// Make the connection to the WEB server + +int connection::connect(char *hostname_opt_port, int tcp_nodelay, int sockbufsiz) { + if(!hostname_opt_port) return 1; + + char *hostname_with_port; + // Check to see if portnumber is specified in the hostnameport + // If not, append :80 + if(!ACE_OS::strchr(hostname_opt_port,':')) { + hostname_with_port = new char[ACE_OS::strlen(hostname_opt_port) + 3]; + ACE_OS::sprintf(hostname_with_port, "%s:%d", hostname_opt_port, 80); + } + else { + hostname_with_port = hostname_opt_port; + } + + // Beyond this point, hostname_with_port is of the form hostname:port + + ACE_INET_Addr server_addr(hostname_with_port); + + // Connect to server + + ACE_SOCK_Connector con; + + if(con.connect(stream_, server_addr) == -1) { + perror("ACE_SOCK_Connector::connect"); + return 1; + } + + + // tcp_nodelay processing. + + // turn off weird ack things + if(tcp_nodelay) { + struct protoent *p = ACE_OS::getprotobyname ("tcp"); + int one = 1; + + if (p && stream_.set_option (p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) { + perror("tcp_nodelay"); + return 1; + } + } + + if(sockbufsiz) + if (stream_.set_option (SOL_SOCKET, + SO_RCVBUF, + (char *) &sockbufsiz, + sizeof sockbufsiz) == -1) { + perror("socket_queue_size"); + return 1; + } + + return 0; +} + +int connection::read(void *buffer, size_t maxlen, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + return stream_.recv(buffer, maxlen); +} + +int connection::write(const void *buffer, size_t maxlen, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + return stream_.send(buffer, maxlen); +} + +int connection::write_n(const void *buffer, size_t len, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + if(stream_.send_n(buffer, len) == -1) + ACE_ERROR_RETURN((LM_ERROR, "Write failed for %s", buffer),1); + return 0; +} + +int connection::read_n(void *buffer, size_t maxlen, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + if(stream_.recv_n(buffer, maxlen) == -1) + ACE_ERROR_RETURN((LM_ERROR, "Read failed.."),1); + return 1; +} + +int connection::close(void) { + stream_.close_reader(); + stream_.close_writer(); + stream_.close(); + return 0; +} + +connection::~connection(void) { + this->close(); +} diff --git a/ACE/apps/JAWS/stress_testing/connection.h b/ACE/apps/JAWS/stress_testing/connection.h new file mode 100644 index 00000000000..db37ff07f35 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/connection.h @@ -0,0 +1,22 @@ +// $Id$ + +#include "global.h" + +#ifndef _D_connection +#define _D_connection +class connection { + +public: + int connect(char *hostname_opt_port, int tcp_nodelay, int sockbufsiz); + int read(void *buffer, size_t maxlen, unsigned int timeout_seconds = 60); + int write(const void *buffer, size_t maxlen, unsigned int timeout_seconds = 60); + int write_n(const void *buffer, size_t len, unsigned int timeout_seconds = 60); + int read_n(void *buffer, size_t maxlen, unsigned int timeout_seconds = 60); + int close(void); + ~connection(void); + +private: + ACE_SOCK_Stream stream_; + char sockbuf[66000]; +}; +#endif diff --git a/ACE/apps/JAWS/stress_testing/cp.cpp b/ACE/apps/JAWS/stress_testing/cp.cpp new file mode 100644 index 00000000000..4829735aaa8 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/cp.cpp @@ -0,0 +1,11 @@ +// $Id$ + +#include "cp.h" + +ACE_RCSID(stress_testing, cp, "$Id$") + +Client_Parameters::Client_Parameters(int i) { + + id = i; + +} diff --git a/ACE/apps/JAWS/stress_testing/cp.h b/ACE/apps/JAWS/stress_testing/cp.h new file mode 100644 index 00000000000..ad2e5ddf31b --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/cp.h @@ -0,0 +1,14 @@ +// $Id$ + +#include "util.h" +#include "stats.h" + +class Client_Parameters { +public: + Client_Parameters(int); + URL *url; + static Stats *stats; + static int tcp_nodelay; + static int sockbufsiz; + int id; +}; diff --git a/ACE/apps/JAWS/stress_testing/global.h b/ACE/apps/JAWS/stress_testing/global.h new file mode 100644 index 00000000000..0d916f2cc41 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/global.h @@ -0,0 +1,31 @@ +// $Id$ + +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Connector.h" +#include "ace/Pipe.h" +#include "ace/SOCK_Stream.h" +#include "ace/INET_Addr.h" +#include "ace/Profile_Timer.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" + +// FUZZ: disable check_for_math_include +#include <math.h> + + + + + + + + + + + diff --git a/ACE/apps/JAWS/stress_testing/http.h b/ACE/apps/JAWS/stress_testing/http.h new file mode 100644 index 00000000000..efce9235e56 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/http.h @@ -0,0 +1,16 @@ +// $Id$ + +#include "global.h" + +#define CONTENT_ENCODING_HEADER "Content-encoding: " +#define CONTENT_TYPE_HEADER "Content-type: " +#define INCOMING_FILE_NAME "/tmp/sumedh.web.inc" +#define TEMPORARY_FILE_NAME "/tmp/sumedh.web.tmp" + +#define ENCODING_TAB "./encoding.tab" +#define CONTENT_TAB "./content.tab" + +int demime(void); +int decode(char *encoding); +int view(char *content); + diff --git a/ACE/apps/JAWS/stress_testing/http_tester.cpp b/ACE/apps/JAWS/stress_testing/http_tester.cpp new file mode 100644 index 00000000000..eb086262317 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/http_tester.cpp @@ -0,0 +1,172 @@ +// $Id$ + +#include "client.h" + +ACE_RCSID(stress_testing, http_tester, "$Id$") + +int Client_Parameters::tcp_nodelay; +int Client_Parameters::sockbufsiz; +Stats *Client_Parameters::stats; + +static void * +client_thread(void *data) +{ + Client_Parameters *cp = (Client_Parameters *) data; + float latency = 0, throughput; + URL *u = cp->url; + + // Check for presence of protocol, hostname and filename. + + if(!(u->get_protocol() && u->get_hostname() && u->get_filename())) { + cerr << "Invalid URL" << endl; + return NULL; + } + + cp->stats->i_have_started(cp->id); + + // Attempt connection + connection webserver; + + if(webserver.connect(u->get_hostname(), cp->tcp_nodelay, cp->sockbufsiz)) return NULL; + // Send the request now. + + + char request[BUFSIZ]; + + ACE_Profile_Timer throughput_timer, latency_timer; + throughput_timer.start(); + latency_timer.start(); + ACE_OS::sprintf(request,"GET /%s HTTP/1.0\r\n\r\n",u->get_filename()); + webserver.write_n(request, strlen(request)) ; + + char buffer[BUFSIZ]; + ssize_t num_read = 0, total_read = 0; + unsigned int first_time = 1; + for(;;) { + num_read = webserver.read(buffer, sizeof buffer); + if(first_time) { + ACE_Profile_Timer::ACE_Elapsed_Time et; + latency_timer.stop(); + latency_timer.elapsed_time(et); + latency = et.real_time; + first_time = 0; + } + if(num_read <= 0) + break; + total_read += num_read; + } + cp->stats->i_am_done(cp->id); + ACE_Profile_Timer::ACE_Elapsed_Time et; + throughput_timer.stop(); + throughput_timer.elapsed_time(et); + throughput = (8 * total_read/et.real_time) / (1000 * 1000); //pow(10,6) ; + cp->stats->log(cp->id, throughput, latency); + webserver.close(); + return NULL; +} + +int driver(char *id, int total_num, float requests_sec, char *url1, float p1, char *url2, float p2, char *url3, float p3, int tcp_nodelay, int sockbufsiz) { + + // construct the client parameters packet + + Client_Parameters::tcp_nodelay = tcp_nodelay; + Client_Parameters::sockbufsiz = sockbufsiz; + + Client_Parameters::stats = new Stats(total_num); + + int missed_deadlines = 0; + // sleep_time is in microseconds, and requests_sec is per second, hence the pow(10,6) + float sleep_time = (1/requests_sec) * (1000.0 * 1000.0); // pow(10,6); + float delta = 0; + srand(time(NULL)); + for(int i = 0; i < total_num; i++) { // i is used as a id for threads + ACE_Profile_Timer timer; + if(sleep_time < delta) + { + // cerr << "Requested rate is too high, sleep_time == " << sleep_time << ", and delta = " << delta << ", after " << i << " iterations! " << endl; + missed_deadlines++; + } + else + { + ACE_Time_Value tv(0, (long int) (sleep_time - delta)); + ACE_OS::sleep(tv); + timer.start(); + } + Client_Parameters *cp = new Client_Parameters(i); + + double r = ((double)rand()/(double)RAND_MAX); + // cerr << " choosing between " << url1 << url2 << url3 << " with r == " << r; + if(r <= p1) cp->url = new URL(url1); + if( (r > p1) && (r <= (p1 + p2))) cp->url = new URL(url2); + if( (r > (p1 + p2)) && (r <= p1 + p2 + p3)) cp->url = new URL(url3); + // cerr << "The URL being requested is " << cp->url->get_filename() << endl; + + + (ACE_Thread_Manager::instance ())->spawn(client_thread, (void *) cp); + timer.stop(); + ACE_Profile_Timer::ACE_Elapsed_Time et; + timer.elapsed_time(et); + delta = ( (0.4 * fabs(et.real_time * (1000 * 1000))) + (0.6 * delta) ); // pow(10,6) + } + + // Join the other threads.. + (ACE_Thread_Manager::instance ())->wait(); + // Now output the data for this test + cout << id; + Client_Parameters::stats->output(); + cout << endl; + if (missed_deadlines != 0) + { + cout << "missed deadlines " << missed_deadlines << endl; + cout << "missed deadlines as a % of total requests: " << (float) missed_deadlines / total_num * 100 << endl; + } + return 0; +} + + +main(int argc, char **argv) +{ + // This will set the global scale factor if the ACE_SCALE_FACTOR + // environment variable is set. + ACE_High_Res_Timer::get_env_global_scale_factor (); + + if(argc < 3) { + cerr << "Usage: " << argv[0] << " infile outfile " << endl; + cerr << "The input file contains lines, with the following fields: " << endl; + cerr << "experiment_id total_number_of_requests request_rate url1 p1 url2 p2 url3 p3 TCP_NODELAY SOCKET_RECV_BUFSIZ " << endl; + + return 1; + } + + FILE *fp = fopen(argv[1],"r"); + if(fp == NULL) { + perror("fopen"); + return 2; + } + close(1); + int fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd == -1) { + perror("open"); + return 3; + } + + + int total_num, tcp, sock; + char *id = new char[BUFSIZ]; + float rate, p1, p2, p3; + char *url1 = new char[BUFSIZ]; + char *url2 = new char[BUFSIZ]; + char *url3 = new char[BUFSIZ]; + + + while(!feof(fp)) { + fscanf(fp,"%s %d %f %s %f %s %f %s %f %d %d\n", id, &total_num, &rate, url1, &p1, url2, &p2, url3, &p3, &tcp, &sock); + if (id[0] == '#') continue; + fprintf(stderr,"----\n"); + fprintf(stderr,"\tNow performing experiment:%s\n\tSending %d requests at %f requests/second\n", id, total_num, rate); + driver(id, total_num, rate, url1, p1, url2, p2, url3, p3, tcp, sock); + } + fclose(fp); + close(fd); + return 0; +} diff --git a/ACE/apps/JAWS/stress_testing/out b/ACE/apps/JAWS/stress_testing/out new file mode 100644 index 00000000000..c237b7f38bc --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/out @@ -0,0 +1,2 @@ +1.0 0.47895 0.00859167 1 +2.0 0.562603 0.00185976 1 diff --git a/ACE/apps/JAWS/stress_testing/stats.cpp b/ACE/apps/JAWS/stress_testing/stats.cpp new file mode 100644 index 00000000000..6e71b91c014 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/stats.cpp @@ -0,0 +1,88 @@ +// $Id$ + +#include "stats.h" + +ACE_RCSID(stress_testing, stats, "$Id$") + +Stats::Stats(int size) { + throughput_ = new float[size]; + latency_ = new float[size]; + thread_count_ = size; + init_fini_ = new Init_Fini_t[2*size]; + for(int i = 0; i < size; i++) + throughput_[i] = latency_[i] = 0; +} + +void Stats::log(int id, float throughput, float latency) { + throughput_[id] = throughput; + latency_[id] = latency; +} + +// Unused for now. +void Stats::print(char *message) { + + ACE_UNUSED_ARG (message); + + // char time_buf[64]; + // long ltime; + // time(<ime); + + // ACE_OS::ctime_r(<ime, time_buf, sizeof time_buf); + + // if(ACE_OS::gettimeofday() == -1) { + // perror("gettimeofday"); + // } + // time_buf[strlen(time_buf)-1] = 0; + // printf("%010ld%09ld \t %s %s\n", tp.tv_sec, tp.tv_usec, time_buf, message); +} + + +int comp(const void *a, const void *b) { + + Init_Fini_t *A = (Init_Fini_t *)a; + Init_Fini_t *B = (Init_Fini_t *)b; + + return (A->timestamp < B->timestamp) ? -1 : (A->timestamp > B->timestamp); +} + + +void Stats::output() { + int i; + float tavg = 0, lavg = 0; + + qsort(init_fini_, 2*thread_count_, sizeof(Init_Fini_t), comp); + + int max = 0,thread_peak = 0; + + for(i = 0; i < 2*thread_count_; i++) { + // cerr << " " << ((init_fini_[i].type == THREAD_START) ? "START": "END") << " " << init_fini_[i].timestamp.sec() << "." << init_fini_[i].timestamp.usec() << endl; + if(init_fini_[i].type == THREAD_START) { + if(++thread_peak > max) + max = thread_peak; + } + else thread_peak--; + } + for(i = 0; i < thread_count_; i++) { + tavg += throughput_[i]; + lavg += latency_[i]; + } + cout << " " << tavg/thread_count_ << " " << lavg/thread_count_ << " " << max; +} + + +void Stats::i_have_started(int id) { + + init_fini_[2*id].type = THREAD_START; + init_fini_[2*id].timestamp = ACE_OS::gettimeofday(); + +} + +void Stats::i_am_done(int id) { + + init_fini_[(2*id)+1].type = THREAD_END; + + init_fini_[(2*id)+1].timestamp = ACE_OS::gettimeofday(); + +} + + diff --git a/ACE/apps/JAWS/stress_testing/stats.h b/ACE/apps/JAWS/stress_testing/stats.h new file mode 100644 index 00000000000..b5ef4a4f4a0 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/stats.h @@ -0,0 +1,31 @@ +// $Id$ + +#include "global.h" + +#ifndef _D_Stats +#define _D_Stats + +#define THREAD_START 42 +#define THREAD_END 43 + +class Init_Fini_t { +public: + int type; // 0 is start, 1 is end + ACE_Time_Value timestamp; +}; + +class Stats { +public: + Stats(int); + void log(int, float, float); + void i_have_started(int); + void i_am_done(int); + void print (char *); + void output(); +private: + float *throughput_; + float *latency_; + Init_Fini_t *init_fini_; // Array (2n deep) to count peak no. of active threads + int thread_count_; +}; +#endif diff --git a/ACE/apps/JAWS/stress_testing/util.cpp b/ACE/apps/JAWS/stress_testing/util.cpp new file mode 100644 index 00000000000..29cd92ef143 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/util.cpp @@ -0,0 +1,60 @@ +// $Id$ + +#include "util.h" + +ACE_RCSID(stress_testing, util, "$Id$") + +URL::URL(char *input_buf) { + + char *buffer = new char[BUFSIZ]; + + ACE_OS::strcpy(buffer,input_buf); + if(buffer == NULL) + return; + + char *temp; + char *lasts; + + if((temp = ACE_OS::strtok_r(buffer,": ",&lasts))) { + protocol_ = (char *) ACE_OS::malloc(strlen(temp) + 1); + ACE_OS::strcpy(protocol_, temp); + } + + if((temp = ACE_OS::strtok_r(NULL,"/",&lasts))) { + hostname_ = (char *) ACE_OS::malloc(strlen(temp) + 1); + ACE_OS::strcpy(hostname_, temp); + } + if((temp = ACE_OS::strtok_r(NULL,"\0",&lasts))) { + filename_ = (char *) malloc(strlen(temp) + 1); + ACE_OS::strcpy(filename_, temp); + } + else { + filename_ = (char *) malloc(strlen(INDEX_NAME) + 1); + ACE_OS::strcpy(filename_,INDEX_NAME); + } +} + +char *URL::get_protocol(void) { + return protocol_; +} + +char *URL::get_hostname(void) { + return hostname_; +} + +char *URL::get_filename(void) { + return filename_; +} + + + + + +void cleanup(void) { + unlink(TEMPORARY_FILE_NAME); + unlink(INCOMING_FILE_NAME); +} + +void sigint(int) { + cleanup(); +} diff --git a/ACE/apps/JAWS/stress_testing/util.h b/ACE/apps/JAWS/stress_testing/util.h new file mode 100644 index 00000000000..875a8cd80e0 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/util.h @@ -0,0 +1,34 @@ +// $Id$ + +#include "connection.h" + +#ifndef _D_URL +#define _D_URL +class URL { + +public: + + URL(char *buffer); + + char *get_protocol(); + char *get_hostname(); + char *get_filename(); + +private: + char *protocol_; + char *hostname_; + char *filename_; +}; + +void cleanup(void); +void sigint(int); +int copier(connection in); + +#define INDEX_NAME "/index.html" +#define INCOMING_FILE_NAME "/tmp/sumedh.web.inc" +#define TEMPORARY_FILE_NAME "/tmp/sumedh.web.tmp" +#endif + + + + |