• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

StatSystem.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026   StatSystem.cc --
00027   Created On          : Fri Apr 3 19:41:39 1998
00028  ****************************************************************************/
00029 #include "Main.h"
00030 #include "StatSystem.h"
00031 #include "P_EventSystem.h"
00032 #include "Error.h"
00033 #include "ProcessManager.h"
00034 #include "ProxyConfig.h"
00035 #include "StatPages.h"
00036 #include "HTTP.h"
00037 #include "I_Layout.h"
00038 
00039 // defines
00040 
00041 #define SNAP_USAGE_PERIOD         HRTIME_SECONDS(2)
00042 
00043 
00044 // variables
00045 
00046 #ifdef DEBUG
00047 ink_mutex http_time_lock;
00048 time_t last_http_local_time;
00049 #endif
00050 ink_stat_lock_t global_http_trans_stat_lock;
00051 ink_unprot_global_stat_t global_http_trans_stats[MAX_HTTP_TRANS_STATS];
00052 #ifndef USE_LOCKS_FOR_DYN_STATS
00053 inkcoreapi ink_unprot_global_stat_t global_dyn_stats[MAX_DYN_STATS - DYN_STAT_START];
00054 #else
00055 inkcoreapi ink_prot_global_stat_t global_dyn_stats[MAX_DYN_STATS - DYN_STAT_START];
00056 #endif
00057 
00058 Ptr<ProxyMutex> rusage_snap_mutex;
00059 struct rusage rusage_snap;
00060 struct rusage rusage_snap_old;
00061 ink_hrtime rusage_snap_time;
00062 ink_hrtime rusage_snap_time_old;
00063 int snap_stats_every = 60;
00064 
00065 ink_hrtime http_handler_times[MAX_HTTP_HANDLER_EVENTS];
00066 int http_handler_counts[MAX_HTTP_HANDLER_EVENTS];
00067 
00068 
00069 char snap_filename[PATH_NAME_MAX+1] = DEFAULT_SNAP_FILENAME;
00070 
00071 #define DEFAULT_PERSISTENT
00072 
00073 #ifndef DEFAULT_PERSISTENT
00074 static int persistent_stats[] = {
00075   http_incoming_requests_stat
00076 };
00077 #else
00078 static int non_persistent_stats[] = {
00079   ////////////////////////////
00080   // Start of Cluster stats
00081   ////////////////////////////
00082   cluster_connections_open_stat,
00083   cluster_connections_openned_stat,
00084   cluster_con_total_time_stat,
00085   cluster_ctrl_msgs_sent_stat,
00086   cluster_slow_ctrl_msgs_sent_stat,
00087   cluster_ctrl_msgs_recvd_stat,
00088   cluster_slow_ctrl_msgs_recvd_stat,
00089   cluster_ctrl_msgs_send_time_stat,
00090   cluster_ctrl_msgs_recv_time_stat,
00091   cluster_read_bytes_stat,
00092   cluster_write_bytes_stat,
00093   cluster_op_delayed_for_lock_stat,
00094   cluster_connections_locked_stat,
00095   cluster_connections_bumped_stat,
00096   cluster_nodes_stat,
00097   cluster_net_backup_stat,
00098   cluster_machines_allocated_stat,
00099   cluster_machines_freed_stat,
00100   cluster_configuration_changes_stat,
00101   cluster_delayed_reads_stat,
00102   cluster_byte_bank_used_stat,
00103   cluster_alloc_data_news_stat,
00104   cluster_write_bb_mallocs_stat,
00105   cluster_partial_reads_stat,
00106   cluster_partial_writes_stat,
00107   cluster_cache_outstanding_stat,
00108   cluster_remote_op_timeouts_stat,
00109   cluster_remote_op_reply_timeouts_stat,
00110   cluster_chan_inuse_stat,
00111   cluster_open_delays_stat,
00112   cluster_open_delay_time_stat,
00113   cluster_cache_callbacks_stat,
00114   cluster_cache_callback_time_stat,
00115   cluster_cache_rmt_callbacks_stat,
00116   cluster_cache_rmt_callback_time_stat,
00117   cluster_cache_lkrmt_callbacks_stat,
00118   cluster_cache_lkrmt_callback_time_stat,
00119   cluster_thread_steal_expires_stat,
00120   cluster_local_connections_closed_stat,
00121   cluster_local_connection_time_stat,
00122   cluster_remote_connections_closed_stat,
00123   cluster_remote_connection_time_stat,
00124   cluster_rdmsg_assemble_time_stat,
00125   cluster_ping_time_stat,
00126   cluster_setdata_no_clustervc_stat,
00127   cluster_setdata_no_tunnel_stat,
00128   cluster_setdata_no_cachevc_stat,
00129   cluster_setdata_no_cluster_stat,
00130   cluster_vc_write_stall_stat,
00131   cluster_no_remote_space_stat,
00132   cluster_level1_bank_stat,
00133   cluster_multilevel_bank_stat,
00134   cluster_vc_cache_insert_lock_misses_stat,
00135   cluster_vc_cache_inserts_stat,
00136   cluster_vc_cache_lookup_lock_misses_stat,
00137   cluster_vc_cache_lookup_hits_stat,
00138   cluster_vc_cache_lookup_misses_stat,
00139   cluster_vc_cache_scans_stat,
00140   cluster_vc_cache_scan_lock_misses_stat,
00141   cluster_vc_cache_purges_stat,
00142   cluster_write_lock_misses_stat,
00143   /////////////////////////////////////
00144   // Start of Scheduled Update stats
00145   /////////////////////////////////////
00146   // DNS
00147   //dns_success_time_stat
00148 };
00149 #endif
00150 
00151 #define _HEADER \
00152 DynamicStatsString_t DynamicStatsStrings[] = {
00153 
00154 #define _FOOTER };
00155 #define _D(_x) { _x, #_x },
00156 
00157 #include "DynamicStats.h"
00158 #undef _HEADER
00159 #undef _FOOTER
00160 #undef _D
00161 
00162 
00163 
00164 // functions
00165 
00166 static int
00167 persistent_stat(int i)
00168 {
00169 #ifndef DEFAULT_PERSISTENT
00170   for (unsigned j = 0; j < countof(persistent_stats); j++)
00171     if (persistent_stats[j] == i)
00172       return 1;
00173   return 0;
00174 #else
00175   for (unsigned j = 0; j < countof(non_persistent_stats); j++)
00176     if (non_persistent_stats[j] == i)
00177       return 0;
00178   return 1;
00179 #endif
00180 }
00181 
00182 static int
00183 open_stats_snap()
00184 {
00185   int fd = socketManager.open(snap_filename,
00186                               O_CREAT | O_RDWR | _O_ATTRIB_NORMAL);
00187   if (fd < 0) {
00188     Warning("unable to open %s: %s", snap_filename, strerror(-fd));
00189     return -1;
00190   }
00191   return fd;
00192 }
00193 
00194 static void
00195 clear_stats()
00196 {
00197   int i = 0;
00198 
00199   int stats_size = MAX_HTTP_TRANS_STATS - NO_HTTP_TRANS_STATS - 1;
00200   for (i = 0; i < stats_size; i++) {
00201     if (persistent_stat(i + NO_HTTP_TRANS_STATS)) {
00202       global_http_trans_stats[i].sum = 0;
00203       global_http_trans_stats[i].count = 0;
00204     }
00205   }
00206   stats_size = MAX_DYN_STATS - NO_DYN_STATS - 1;
00207   for (i = 0; i < stats_size; i++) {
00208     if (persistent_stat(i + NO_DYN_STATS)) {
00209       global_dyn_stats[i].sum = 0;
00210       global_dyn_stats[i].count = 0;
00211     }
00212   }
00213 
00214   socketManager.unlink(snap_filename);
00215   Debug("stats", "clear_stats: clearing statistics");
00216 }
00217 
00218 static void
00219 read_stats_snap()
00220 {
00221   unsigned int version;
00222   unsigned int version_read;
00223   int count;
00224   int fd = -1;
00225   int i = 0;
00226   int stats_size = -1;
00227 
00228   version = STATS_MAJOR_VERSION;
00229 
00230   if ((fd = open_stats_snap()) < 0)
00231     goto Lmissmatch;
00232 
00233   // read and verify snap
00234   if (socketManager.read(fd, (char *) &version_read, sizeof(version_read))
00235       != sizeof(version_read))
00236     goto Lmissmatch;
00237   if (version != version_read)
00238     goto Lmissmatch;
00239   stats_size = MAX_HTTP_TRANS_STATS - NO_HTTP_TRANS_STATS + MAX_DYN_STATS - NO_DYN_STATS;
00240   if (socketManager.read(fd, (char *) &count, sizeof(count)) != sizeof(count))
00241     goto Lmissmatch;
00242   if (count != stats_size)
00243     goto Lmissmatch;
00244 
00245   stats_size = MAX_HTTP_TRANS_STATS - NO_HTTP_TRANS_STATS;
00246   for (i = 0; i < stats_size; i++) {
00247     if (socketManager.read(fd, (char *) &global_http_trans_stats[i].sum, sizeof(global_http_trans_stats[i].sum))
00248         != sizeof(global_http_trans_stats[i].sum))
00249       goto Lmissmatch;
00250     if (socketManager.read(fd, (char *) &global_http_trans_stats[i].count, sizeof(global_http_trans_stats[i].count))
00251         != sizeof(global_http_trans_stats[i].count))
00252       goto Lmissmatch;
00253   }
00254   stats_size = MAX_DYN_STATS - NO_DYN_STATS;
00255   for (i = 0; i < stats_size; i++) {
00256     if (socketManager.read(fd, (char *) &global_dyn_stats[i].sum, sizeof(global_dyn_stats[i].sum))
00257         != sizeof(global_dyn_stats[i].sum))
00258       goto Lmissmatch;
00259     if (socketManager.read(fd, (char *) &global_dyn_stats[i].count, sizeof(global_dyn_stats[i].count))
00260         != sizeof(global_dyn_stats[i].count))
00261       goto Lmissmatch;
00262   }
00263   Debug("stats", "read_stats_snap: read statistics");
00264 
00265   // close(fd);
00266   socketManager.close(fd);
00267   return;
00268 
00269 Lmissmatch:
00270   Note("clearing statistics");
00271   clear_stats();
00272   //close(fd);
00273   socketManager.close(fd);
00274 }
00275 
00276 static void
00277 write_stats_snap()
00278 {
00279   int fd = 0;
00280   int version = STATS_MAJOR_VERSION;
00281   char *buf = NULL;
00282 
00283   if ((fd = open_stats_snap()) < 0) {
00284     Warning("unable to snap statistics");
00285     return;
00286   }
00287 
00288   {
00289     int stats_size = MAX_HTTP_TRANS_STATS - NO_HTTP_TRANS_STATS + MAX_DYN_STATS - NO_DYN_STATS;
00290     int buf_size = sizeof(unsigned int) * 3 + stats_size * (sizeof(global_dyn_stats[0].sum) + sizeof(global_dyn_stats[0].count));
00291     buf = (char *)ats_malloc(buf_size);
00292     char *p = buf;
00293     int i = 0;
00294 
00295     memcpy(p, (char *) &version, sizeof(version));
00296     p += sizeof(version);
00297     memcpy(p, (char *) &stats_size, sizeof(stats_size));
00298     p += sizeof(stats_size);
00299 
00300     stats_size = MAX_HTTP_TRANS_STATS - NO_HTTP_TRANS_STATS;
00301     STAT_LOCK_ACQUIRE(&(global_http_trans_stat_lock));
00302     for (i = 0; i < stats_size; i++) {
00303       memcpy(p, (char *) &global_http_trans_stats[i].sum, sizeof(global_http_trans_stats[i].sum));
00304       p += sizeof(global_http_trans_stats[i].sum);
00305       memcpy(p, (char *) &global_http_trans_stats[i].count, sizeof(global_http_trans_stats[i].count));
00306       p += sizeof(global_http_trans_stats[i].count);
00307     }
00308     STAT_LOCK_RELEASE(&(global_http_trans_stat_lock));
00309     stats_size = MAX_DYN_STATS - NO_DYN_STATS;
00310     for (i = 0; i < stats_size; i++) {
00311       // INKqa09981 (Clearing Host Database and DNS Statistics)
00312       ink_statval_t count, sum;
00313       READ_GLOBAL_DYN_STAT(i, count, sum);
00314       memcpy(p, (char *) &sum, sizeof(sum));
00315       p += sizeof(sum);
00316       memcpy(p, (char *) &count, sizeof(count));
00317       p += sizeof(count);
00318     }
00319     memcpy(p, (char *) &version, sizeof(version));
00320 
00321     if (socketManager.write(fd, buf, buf_size) != buf_size) {
00322       Warning("unable to snap statistics");
00323       ats_free(buf);
00324       socketManager.close(fd);
00325       return;
00326     }
00327   }
00328   ats_free(buf);
00329   socketManager.close(fd);
00330   Debug("stats", "snapped stats");
00331 }
00332 
00333 struct SnapStatsContinuation: public Continuation
00334 {
00335   int mainEvent(int /* event ATS_UNUSED */, Event *e ATS_UNUSED)
00336   {
00337     write_stats_snap();
00338     e->schedule_every(HRTIME_SECONDS(snap_stats_every));
00339     return EVENT_CONT;
00340   }
00341   SnapStatsContinuation():Continuation(new_ProxyMutex())
00342   {
00343     SET_HANDLER(&SnapStatsContinuation::mainEvent);
00344   }
00345 };
00346 
00347 static void
00348 take_rusage_snap()
00349 {
00350   rusage_snap_old = rusage_snap;
00351   rusage_snap_time_old = rusage_snap_time;
00352   int retries = 3;
00353   while (retries--) {
00354     if (getrusage(RUSAGE_SELF, &rusage_snap) < 0) {
00355       if (errno == EINTR)
00356         continue;
00357       Note("getrusage [%d %s]", errno, strerror(errno));
00358     } else
00359       rusage_snap_time = ink_get_hrtime();
00360     break;
00361   }
00362   Debug("rusage", "took rusage snap %" PRId64"", rusage_snap_time);
00363 }
00364 
00365 struct SnapCont;
00366 typedef int (SnapCont::*SnapContHandler) (int, void *);
00367 
00368 struct SnapCont: public Continuation
00369 {
00370   int mainEvent(int /* event ATS_UNUSED */, Event * e)
00371   {
00372     take_rusage_snap();
00373     e->schedule_every(SNAP_USAGE_PERIOD);
00374     return EVENT_CONT;
00375   }
00376   SnapCont(ProxyMutex * m):Continuation(m)
00377   {
00378     SET_HANDLER((SnapContHandler) & SnapCont::mainEvent);
00379   }
00380 };
00381 
00382 void
00383 start_stats_snap()
00384 {
00385   eventProcessor.schedule_every(new SnapCont(rusage_snap_mutex), SNAP_USAGE_PERIOD, ET_CALL);
00386   if (snap_stats_every)
00387     eventProcessor.schedule_every(new SnapStatsContinuation(), HRTIME_SECONDS(snap_stats_every), ET_CALL);
00388   else
00389     Warning("disabling statistics snap");
00390 }
00391 
00392 static Action *
00393 stat_callback(Continuation * cont, HTTPHdr * header)
00394 {
00395   URL *url;
00396   int length;
00397   const char *path;
00398   char *result = NULL;
00399   int result_size;
00400   bool empty;
00401 
00402   url = header->url_get();
00403   path = url->path_get(&length);
00404 
00405   char *buffer = NULL;
00406   int buffer_len = 0;
00407   int num_prefix_buffer;
00408 
00409   char *var_prefix = (char *)alloca((length + 1) * sizeof(char));
00410 
00411   memset(var_prefix, 0, ((length + 1) * sizeof(char)));
00412   if (path && length > 0)
00413     ink_strlcpy(var_prefix, path, length + 1);
00414 
00415   num_prefix_buffer = RecGetRecordPrefix_Xmalloc(var_prefix, &buffer, &buffer_len);
00416   empty = (num_prefix_buffer == 0);
00417 
00418   if (!empty) {
00419     result_size = (buffer_len + 16) * sizeof(char);
00420     result = (char *)ats_malloc(result_size);
00421     memset(result, 0, result_size);
00422 
00423     snprintf(result, result_size - 7, "<pre>\n%s", buffer);
00424   }
00425 
00426 
00427   if (!empty) {
00428     StatPageData data;
00429 
00430     ink_strlcat(result, "</pre>\n", result_size);
00431 
00432     data.data = result;
00433     data.length = strlen(result);
00434     cont->handleEvent(STAT_PAGE_SUCCESS, &data);
00435   } else {
00436     ats_free(result);
00437     cont->handleEvent(STAT_PAGE_FAILURE, NULL);
00438   }
00439   ats_free(buffer);
00440 
00441   return ACTION_RESULT_DONE;
00442 }
00443 
00444 static Action *
00445 testpage_callback(Continuation * cont, HTTPHdr *)
00446 {
00447   const int buf_size = 64000;
00448   char *buffer = (char *)ats_malloc(buf_size);
00449 
00450   for (int i = 0; i < buf_size; i++) {
00451     buffer[i] = (char) ('a' + (i % 26));
00452   }
00453   buffer[buf_size - 1] = '\0';
00454 
00455   StatPageData data;
00456 
00457   data.data = buffer;
00458   data.length = strlen(buffer);
00459   cont->handleEvent(STAT_PAGE_SUCCESS, &data);
00460 
00461   return ACTION_RESULT_DONE;
00462 }
00463 
00464 static void
00465 testpage_callback_init()
00466 {
00467   statPagesManager.register_http("test", testpage_callback);
00468 }
00469 
00470 void
00471 initialize_all_global_stats()
00472 {
00473   int istat, i;
00474   char snap_file[PATH_NAME_MAX + 1];
00475   ats_scoped_str rundir(RecConfigReadRuntimeDir());
00476 
00477   if (access(rundir, R_OK | W_OK) == -1) {
00478     Warning("Unable to access() local state directory '%s': %d, %s", (const char *)rundir, errno, strerror(errno));
00479     Warning(" Please set 'proxy.config.local_state_dir' to allow statistics collection");
00480   }
00481   REC_ReadConfigString(snap_file, "proxy.config.stats.snap_file", PATH_NAME_MAX);
00482   Layout::relative_to(snap_filename, sizeof(snap_filename), (const char *)rundir, snap_file);
00483   Debug("stats", "stat snap filename %s", snap_filename);
00484 
00485   statPagesManager.register_http("stat", stat_callback);
00486 
00487   testpage_callback_init();
00488 
00489   read_stats_snap();
00490   rusage_snap_mutex = new_ProxyMutex();
00491   take_rusage_snap();
00492   take_rusage_snap();           // fill in _old as well
00493 
00494   STAT_LOCK_INIT(&(global_http_trans_stat_lock), "Global Http Stats Lock");
00495 
00496   for (istat = NO_HTTP_TRANS_STATS; istat < MAX_HTTP_TRANS_STATS; istat++) {
00497     if (!persistent_stat(istat)) {
00498       INITIALIZE_GLOBAL_TRANS_STATS(global_http_trans_stats[istat]);
00499     }
00500   }
00501 
00502   for (istat = NO_DYN_STATS; istat < MAX_DYN_STATS; istat++) {
00503     if (!persistent_stat(istat)) {
00504       i = istat - DYN_STAT_START;
00505       INITIALIZE_GLOBAL_DYN_STATS(global_dyn_stats[i], "Dyn Stat Lock");
00506     }
00507   }
00508 
00509   // TODO: HMMMM, wtf does this do? The following is that this 
00510   // function does:
00511   // ink_atomic_swap(&this->f_update_lock, (void *) func)
00512   //
00513   // pmgmt->record_data->registerUpdateLockFunc(tmp_stats_lock_function);
00514 
00515 #ifdef DEBUG
00516   ink_mutex_init(&http_time_lock, "Http Time Function Lock");
00517   last_http_local_time = 0;
00518 #endif
00519 
00520   clear_http_handler_times();
00521 }
00522 
00523 //void *
00524 //tmp_stats_lock_function(UpdateLockAction action)
00525 //{
00526 //  stats_lock_function((void *) (&global_http_trans_stat_lock), action);
00527 //
00528 //  return NULL;
00529 //}
00530 
00531 //void *
00532 //stats_lock_function(void *data, UpdateLockAction action)
00533 //{
00534 //  if (action == UPDATE_LOCK_ACQUIRE) {
00535 //    STAT_LOCK_ACQUIRE((ink_stat_lock_t *) data);
00536 //  } else {
00537 //    STAT_LOCK_RELEASE((ink_stat_lock_t *) data);
00538 //  }
00539 //
00540 //  return NULL;
00541 //}
00542 
00543 void *
00544 dyn_stats_int_msecs_to_float_seconds_cb(void *data, void *res)
00545 {
00546   ink_statval_t count, sum;
00547   READ_DYN_STAT((long) data, count, sum);
00548 
00549   float r;
00550   if (count == 0) {
00551     r = 0.0;
00552   } else {
00553     r = ((float) sum) / 1000.0;
00554   }
00555   *(float *) res = r;
00556   return res;
00557 }
00558 
00559 void *
00560 dyn_stats_count_cb(void *data, void *res)
00561 {
00562   ink_statval_t count, sum;
00563   READ_DYN_STAT((long) data, count, sum);
00564   (void)sum;
00565   ink_atomic_swap((ink_statval_t *) res, count);
00566   return res;
00567 }
00568 
00569 void *
00570 dyn_stats_sum_cb(void *data, void *res)
00571 {
00572   ink_statval_t count, sum;
00573   READ_DYN_STAT((long) data, count, sum);
00574   (void)count;
00575   ink_atomic_swap((ink_statval_t *) res, sum);
00576   return res;
00577 }
00578 
00579 void *
00580 dyn_stats_avg_cb(void *data, void *res)
00581 {
00582   ink_statval_t count, sum;
00583   READ_DYN_STAT((long) data, count, sum);
00584   if (count == 0) {
00585     *(float *) res = 0.0;
00586   } else {
00587     *(float *) res = (float) sum / (float) count;
00588   }
00589   return res;
00590 }
00591 
00592 void *
00593 dyn_stats_fsum_cb(void *data, void *res)
00594 {
00595   ink_statval_t count, sum;
00596   READ_DYN_STAT((long) data, count, sum);
00597   (void)count;
00598   *(float *) res = (double) sum;
00599   return res;
00600 }
00601 
00602 void *
00603 dyn_stats_favg_cb(void *data, void *res)
00604 {
00605   ink_statval_t count, sum;
00606   READ_DYN_STAT((long) data, count, sum);
00607   if (count == 0) {
00608     *(float *) res = 0.0;
00609   } else {
00610     *(float *) res = (double) sum / (double) count;
00611   }
00612   return res;
00613 }
00614 
00615 void *
00616 dyn_stats_time_seconds_cb(void *data, void *res)
00617 {
00618   ink_statval_t count, sum;
00619   float r;
00620   READ_DYN_STAT((long) data, count, sum);
00621   if (count == 0) {
00622     r = 0.0;
00623   } else {
00624     r = (float) sum / (float) count;
00625     r = r / (float) HRTIME_SECOND;
00626   }
00627   *(float *) res = r;
00628   return res;
00629 }
00630 
00631 void *
00632 dyn_stats_time_mseconds_cb(void *data, void *res)
00633 {
00634   ink_statval_t count, sum;
00635   float r;
00636   READ_DYN_STAT((long) data, count, sum);
00637   if (count == 0) {
00638     r = 0.0;
00639   } else {
00640     r = (float) sum / (float) count;
00641     r = r / (float) HRTIME_MSECOND;
00642   }
00643   *(float *) res = r;
00644   return res;
00645 }
00646 
00647 void *
00648 dyn_stats_time_useconds_cb(void *data, void *res)
00649 {
00650   ink_statval_t count, sum;
00651   float r;
00652   READ_DYN_STAT((long) data, count, sum);
00653   if (count == 0) {
00654     r = 0.0;
00655   } else {
00656     r = (float) sum / (float) count;
00657     r = r / (float) HRTIME_USECOND;
00658   }
00659   *(float *) res = r;
00660   return res;
00661 }
00662 
00663 // http trans stat functions
00664 // there is the implicit assumption that the lock has
00665 // been acquired.
00666 void *
00667 http_trans_stats_int_msecs_to_float_seconds_cb(void *data, void *res)
00668 {
00669   ink_statval_t count, sum;
00670   READ_HTTP_TRANS_STAT((long) data, count, sum);
00671 
00672   float r;
00673   if (count == 0) {
00674     r = 0.0;
00675   } else {
00676     r = ((float) sum) / 1000.0;
00677   }
00678   *(float *) res = r;
00679   return res;
00680 }
00681 
00682 void *
00683 http_trans_stats_count_cb(void *data, void *res)
00684 {
00685   ink_statval_t count, sum;
00686   READ_HTTP_TRANS_STAT((long) data, count, sum);
00687   (void)sum;
00688   ink_atomic_swap((ink_statval_t *) res, count);
00689   return res;
00690 }
00691 
00692 void *
00693 http_trans_stats_sum_cb(void *data, void *res)
00694 {
00695   ink_statval_t count, sum;
00696   READ_HTTP_TRANS_STAT((long) data, count, sum);
00697   (void)count;
00698   ink_atomic_swap((ink_statval_t *) res, sum);
00699   return res;
00700 }
00701 
00702 void *
00703 http_trans_stats_avg_cb(void *data, void *res)
00704 {
00705   ink_statval_t count, sum;
00706   READ_HTTP_TRANS_STAT((long) data, count, sum);
00707   if (count == 0) {
00708     *(float *) res = 0.0;
00709   } else {
00710     *(float *) res = (float) sum / (float) count;
00711   }
00712   return res;
00713 }
00714 
00715 void *
00716 http_trans_stats_fsum_cb(void *data, void *res)
00717 {
00718   ink_statval_t count, sum;
00719   READ_HTTP_TRANS_STAT((long) data, count, sum);
00720   (void)count;
00721   *(float *) res = (double) sum;
00722   return res;
00723 }
00724 
00725 void *
00726 http_trans_stats_favg_cb(void *data, void *res)
00727 {
00728   ink_statval_t count, sum;
00729   READ_HTTP_TRANS_STAT((long) data, count, sum);
00730   if (count == 0) {
00731     *(float *) res = 0.0;
00732   } else {
00733     *(float *) res = (double) sum / (double) count;
00734   }
00735   return res;
00736 }
00737 
00738 void *
00739 http_trans_stats_time_seconds_cb(void *data, void *res)
00740 {
00741   ink_statval_t count, sum;
00742   float r;
00743   READ_HTTP_TRANS_STAT((long) data, count, sum);
00744   if (count == 0) {
00745     r = 0.0;
00746   } else {
00747     r = (float) sum / (float) count;
00748     r = r / (float) HRTIME_SECOND;
00749   }
00750   *(float *) res = r;
00751   return res;
00752 }
00753 
00754 void *
00755 http_trans_stats_time_mseconds_cb(void *data, void *res)
00756 {
00757   ink_statval_t count, sum;
00758   float r;
00759   READ_HTTP_TRANS_STAT((long) data, count, sum);
00760   if (count == 0) {
00761     r = 0.0;
00762   } else {
00763     r = (float) sum / (float) count;
00764     r = r / (float) HRTIME_MSECOND;
00765   }
00766   *(float *) res = r;
00767   return res;
00768 }
00769 
00770 void *
00771 http_trans_stats_time_useconds_cb(void *data, void *res)
00772 {
00773   ink_statval_t count, sum;
00774   float r;
00775   READ_HTTP_TRANS_STAT((long) data, count, sum);
00776   if (count == 0) {
00777     r = 0.0;
00778   } else {
00779     r = (float) sum / (float) count;
00780     r = r / (float) HRTIME_USECOND;
00781   }
00782   *(float *) res = r;
00783   return res;
00784 }

Generated by  doxygen 1.7.1