⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsesslog.c

📁 一个WEB服务器的性能测试工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    httperf -- a tool for measuring web server performance    Copyright (C) 2000  Hewlett-Packard Company    Contributed by Richard Carter <carter@hpl.hp.com>    This file is part of httperf, a web server performance measurment    tool.    This program is free software; you can redistribute it and/or    modify it under the terms of the GNU General Public License as    published by the Free Software Foundation; either version 2 of the    License, or (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA    02111-1307 USA*//* Creates sessions at the fixed rate PARAM.RATE.  The session descriptions   are read in from a configuration file.   There is currently no tool that translates from standard log   formats to the format accepted by this module.   An example input file follows:   #   # This file specifies the potentially-bursty uri sequence for a number of   # user sessions.  The format rules of this file are as follows:   #   # Comment lines start with a '#' as the first character.  # anywhere else   # is considered part of the uri.   #   # Lines with only whitespace delimit session definitions (multiple blank   # lines do not generate "null" sessions).   #   # Lines otherwise specify a uri-sequence (1 uri per line).  If the   # first character of the line is whitespace (e.g. space or tab), the   # uri is considered to be part of a burst that is sent out after the   # previous non-burst uri.   #   # session 1 definition (this is a comment)   /foo.html	/pict1.gif	/pict2.gif   /foo2.html	/pict3.gif	/pict4.gif   #session 2 definition   /foo3.html   /foo4.html	/pict5.gif   Any comment on this module contact carter@hpl.hp.com.  */#include <assert.h>#include <ctype.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <httperf.h>#include <conn.h>#include <core.h>#include <event.h>#include <rate.h>#include <session.h>#include <timer.h>/* Maximum number of sessions that can be defined in the configuration   file.  */#define MAX_SESSION_TEMPLATES	1000#define TRUE  (1)#define FALSE (0)#define SESS_PRIVATE_DATA(c)						\  ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset))typedef struct req REQ;struct req  {    REQ *next;    int method;    char *uri;    int uri_len;    char *contents;    int contents_len;    char extra_hdrs[50];	/* plenty for "Content-length: 1234567890" */    int extra_hdrs_len;  };typedef struct burst BURST;struct burst  {    BURST *next;    int num_reqs;    Time user_think_time;    REQ *req_list;  };typedef struct Sess_Private_Data Sess_Private_Data;struct Sess_Private_Data  {    u_int num_calls_in_this_burst; /* # of calls created for this burst */    u_int num_calls_target;	/* total # of calls desired */    u_int num_calls_destroyed;	/* # of calls destroyed so far */    Timer *timer;		/* timer for session think time */    int total_num_reqs;		/* total number of requests in this session */    BURST *current_burst;	/* the current burst we're working on */    REQ *current_req;		/* the current request we're working on */  };/* Methods allowed for a request: */enum  {    HM_DELETE, HM_GET, HM_HEAD, HM_OPTIONS, HM_POST, HM_PUT, HM_TRACE,    HM_LEN  };static const char *call_method_name[] =  {    "DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT", "TRACE"  };static size_t sess_private_data_offset;static int num_sessions_generated;static int num_sessions_destroyed;static Rate_Generator rg_sess;/* This is an array rather than a list because we may want different   httperf clients to start at different places in the sequence of   sessions. */static int num_templates;static int next_session_template;static Sess_Private_Data session_templates[MAX_SESSION_TEMPLATES] =  {    { 0, }  };static voidsess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg){  Sess_Private_Data *priv;  Sess *sess;  assert (et == EV_SESS_DESTROYED && object_is_sess (obj));  sess = (Sess *) obj;  priv = SESS_PRIVATE_DATA (sess);  if (priv->timer)    {      timer_cancel (priv->timer);      priv->timer = 0;    }  if (++num_sessions_destroyed >= param.wsesslog.num_sessions)    core_exit ();}static voidissue_calls (Sess *sess, Sess_Private_Data *priv){  int i, to_create, retval, n;  const char *method_str;  Call *call;  REQ *req;  /* Mimic browser behavior of fetching html object, then a couple of     embedded objects: */  to_create = 1;  if (priv->num_calls_in_this_burst > 0)    to_create = priv->current_burst->num_reqs - priv->num_calls_in_this_burst;  n = session_max_qlen (sess) - session_current_qlen (sess);  if (n < to_create)    to_create = n;  priv->num_calls_in_this_burst += to_create;  for (i = 0; i < to_create; ++i)    {      call = call_new ();      if (!call)	{	  sess_failure (sess);	  return;	}      /* fill in the new call: */      req = priv->current_req;      if (req == NULL)	panic ("%s: internal error, requests ran past end of burst\n",	       prog_name);      method_str = call_method_name[req->method];      call_set_method (call, method_str, strlen (method_str));      call_set_uri (call, req->uri, req->uri_len);      if (req->contents_len > 0)	{	  /* add "Content-length:" header and contents, if necessary: */	  call_append_request_header (call, req->extra_hdrs,				      req->extra_hdrs_len);	  call_set_contents (call, req->contents, req->contents_len);	}      priv->current_req = req->next;      if (DBG > 0)	fprintf (stderr, "%s: accessing URI `%s'\n", prog_name, req->uri);      retval = session_issue_call (sess, call);      call_dec_ref (call);      if (retval < 0)	return;    }}static voiduser_think_time_expired (Timer *t, Any_Type arg){  Sess *sess = arg.vp;  Sess_Private_Data *priv;  assert (object_is_sess (sess));  priv = SESS_PRIVATE_DATA (sess);  priv->timer = 0;  issue_calls (sess, priv);}/* Create a new session and fill in our private information.  */static intsess_create (Any_Type arg){  Sess_Private_Data *priv, *template;  Sess *sess;  if (num_sessions_generated++ >= param.wsesslog.num_sessions)    return -1;  sess = sess_new ();  template = &session_templates[next_session_template];  if (++next_session_template >= num_templates)    next_session_template = 0;  priv = SESS_PRIVATE_DATA (sess);  priv->current_burst = template->current_burst;  priv->current_req = priv->current_burst->req_list;  priv->total_num_reqs = template->total_num_reqs;  priv->num_calls_target = priv->current_burst->num_reqs;  if (DBG > 0)    fprintf (stderr, "Starting session, first burst_len = %d\n",	     priv->num_calls_target);  issue_calls (sess, SESS_PRIVATE_DATA (sess));  return 0;}static voidprepare_for_next_burst (Sess *sess, Sess_Private_Data *priv){  Time think_time;  Any_Type arg;  if (priv->current_burst != NULL)    {      think_time = priv->current_burst->user_think_time;      /* advance to next burst: */      priv->current_burst = priv->current_burst->next;      if (priv->current_burst != NULL)	{	  priv->current_req = priv->current_burst->req_list;	  priv->num_calls_in_this_burst = 0;	  priv->num_calls_target += priv->current_burst->num_reqs;	  assert (!priv->timer);	  arg.vp = sess;	  priv->timer = timer_schedule (user_think_time_expired,					arg, think_time);	}    }}static voidcall_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg){  Sess_Private_Data *priv;  Sess *sess;  Call *call;  assert (et == EV_CALL_DESTROYED && object_is_call (obj));  call = (Call *) obj;  sess = session_get_sess_from_call (call);  priv = SESS_PRIVATE_DATA (sess);  ++priv->num_calls_destroyed;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -