"Fossies" - the Fresh Open Source Software Archive

Member "httperf-0.9.0/src/gen/wsess.c" (7 Apr 2007, 5875 Bytes) of package /linux/www/old/httperf-0.9.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "wsess.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2     httperf -- a tool for measuring web server performance
    3     Copyright 2000-2007 Hewlett-Packard Company and Contributors listed in
    4     AUTHORS file. Originally contributed by David Mosberger-Tang
    5 
    6     This file is part of httperf, a web server performance measurment
    7     tool.
    8 
    9     This program is free software; you can redistribute it and/or
   10     modify it under the terms of the GNU General Public License as
   11     published by the Free Software Foundation; either version 2 of the
   12     License, or (at your option) any later version.
   13     
   14     In addition, as a special exception, the copyright holders give
   15     permission to link the code of this work with the OpenSSL project's
   16     "OpenSSL" library (or with modified versions of it that use the same
   17     license as the "OpenSSL" library), and distribute linked combinations
   18     including the two.  You must obey the GNU General Public License in
   19     all respects for all of the code used other than "OpenSSL".  If you
   20     modify this file, you may extend this exception to your version of the
   21     file, but you are not obligated to do so.  If you do not wish to do
   22     so, delete this exception statement from your version.
   23 
   24     This program is distributed in the hope that it will be useful,
   25     but WITHOUT ANY WARRANTY; without even the implied warranty of
   26     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   27     General Public License for more details.
   28 
   29     You should have received a copy of the GNU General Public License
   30     along with this program; if not, write to the Free Software
   31     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
   32     02110-1301, USA
   33 */
   34 
   35 /* Creates sessions at the fixed rate PARAM.RATE.  */
   36 
   37 #include <assert.h>
   38 #include <ctype.h>
   39 #include <errno.h>
   40 #include <stdio.h>
   41 #include <stdlib.h>
   42 #include <string.h>
   43 
   44 #include <httperf.h>
   45 #include <call.h>
   46 #include <conn.h>
   47 #include <core.h>
   48 #include <event.h>
   49 #include <rate.h>
   50 #include <session.h>
   51 #include <timer.h>
   52 
   53 #define SESS_PRIVATE_DATA(c) \
   54   ((Sess_Private_Data *) ((char *)(c) + sess_private_data_offset))
   55 
   56 typedef struct Sess_Private_Data
   57   {
   58     u_int num_calls_in_this_burst; /* # of calls created for this burst */
   59     u_int num_calls_target; /* total # of calls desired */
   60     u_int num_calls_destroyed;  /* # of calls destroyed so far */
   61     Timer *timer;       /* timer for session think time */
   62   }
   63 Sess_Private_Data;
   64 
   65 static size_t sess_private_data_offset;
   66 
   67 static int num_sessions_generated;
   68 static int num_sessions_destroyed;
   69 static Rate_Generator rg_sess;
   70 
   71 
   72 static void
   73 issue_calls (Sess *sess, Sess_Private_Data *priv)
   74 {
   75   int i, to_create, retval;
   76   Call *call;
   77 
   78   /* Mimic browser behavior of fetching html object, then a couple of
   79      embedded objects: */
   80 
   81   to_create = 1;
   82   if (priv->num_calls_in_this_burst > 0)
   83     to_create = param.burst_len - priv->num_calls_in_this_burst;
   84 
   85   priv->num_calls_in_this_burst += to_create;
   86 
   87   for (i = 0; i < to_create; ++i)
   88     {
   89       call = call_new ();
   90       if (!call)
   91     {
   92       sess_failure (sess);
   93       return;
   94     }
   95 
   96       retval = session_issue_call (sess, call);
   97       call_dec_ref (call);
   98 
   99       if (retval < 0)
  100     return;
  101     }
  102 }
  103 
  104 static void
  105 user_think_time_expired (Timer *t, Any_Type arg)
  106 {
  107   Sess *sess = arg.vp;
  108   Sess_Private_Data *priv;
  109 
  110   assert (object_is_sess (sess));
  111 
  112   priv = SESS_PRIVATE_DATA (sess);
  113   priv->timer = 0;
  114 
  115   issue_calls (sess, priv);
  116 }
  117 
  118 static void
  119 call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
  120 {
  121   Any_Type arg;
  122   Sess *sess;
  123   Call *call;
  124   Sess_Private_Data *priv;
  125 
  126   assert (et == EV_CALL_DESTROYED && object_is_call (obj));
  127 
  128   call = (Call *) obj;
  129   sess = session_get_sess_from_call (call);
  130   priv = SESS_PRIVATE_DATA (sess);
  131 
  132   ++priv->num_calls_destroyed;
  133 
  134   if (priv->num_calls_destroyed >= param.wsess.num_calls)
  135     {
  136       /* we're done with this session */
  137       if (!sess->failed)
  138     sess_dec_ref (sess);
  139     }
  140   else if (priv->num_calls_in_this_burst < param.burst_len)
  141     /* now that we received the reply to the first call in this burst,
  142        create the remaining calls */
  143     issue_calls (sess, priv);
  144   else if (priv->num_calls_destroyed >= priv->num_calls_target)
  145     {
  146       /* we're done with this burst---schedule the user-think-time timer */
  147       priv->num_calls_in_this_burst = 0;
  148       priv->num_calls_target += param.burst_len;
  149       assert (!priv->timer);
  150       arg.vp = sess;
  151       priv->timer = timer_schedule (user_think_time_expired, arg,
  152                     param.wsess.think_time);
  153     }
  154 }
  155 
  156 /* Create a new session.  */
  157 static int
  158 sess_create (Any_Type arg)
  159 {
  160   Sess_Private_Data *priv;
  161   Sess *sess;
  162 
  163   if (num_sessions_generated++ >= param.wsess.num_sessions)
  164     return -1;
  165 
  166   sess = sess_new ();
  167   if (!sess)
  168     return 1;
  169 
  170   priv = SESS_PRIVATE_DATA (sess);
  171 
  172   priv->num_calls_target = param.burst_len;
  173   issue_calls (sess, SESS_PRIVATE_DATA (sess));
  174   return 0;
  175 }
  176 
  177 static void
  178 sess_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
  179 {
  180   Sess_Private_Data *priv;
  181   Sess *sess;
  182 
  183   assert (et == EV_SESS_DESTROYED && object_is_sess (obj));
  184   sess = (Sess *) obj;
  185 
  186   priv = SESS_PRIVATE_DATA (sess);
  187   if (priv->timer)
  188     {
  189       timer_cancel (priv->timer);
  190       priv->timer = 0;
  191     }
  192 
  193   if (++num_sessions_destroyed >= param.wsess.num_sessions)
  194     core_exit ();
  195 }
  196 
  197 static void
  198 init (void)
  199 {
  200   Any_Type arg;
  201 
  202   session_init ();
  203 
  204   sess_private_data_offset = object_expand (OBJ_SESS,
  205                         sizeof (Sess_Private_Data));
  206   rg_sess.rate = &param.rate;
  207   rg_sess.tick = sess_create;
  208   rg_sess.arg.l = 0;
  209 
  210   arg.l = 0;
  211   event_register_handler (EV_SESS_DESTROYED, sess_destroyed, arg);
  212   event_register_handler (EV_CALL_DESTROYED, call_destroyed, arg);
  213 }
  214 
  215 static void
  216 start (void)
  217 {
  218   rate_generator_start (&rg_sess, EV_SESS_DESTROYED);
  219 }
  220 
  221 Load_Generator wsess =
  222   {
  223     "creates session workload",
  224     init,
  225     start,
  226     no_op
  227   };