00001
00002
00003 #include "cmsdiag.hh"
00004 #include "rcsvers.hh"
00005
00006 #ifdef WIN32
00007 #include <windows.h>
00008 #else
00009 #ifdef VXWORKS
00010 #include <taskLib.h>
00011 #include <sysLib.h>
00012 #else
00013 #include <sys/types.h>
00014 #include <unistd.h>
00015 #endif
00016 #endif
00017
00018 #if defined(SUN) && !defined(HAVE_SYSINFO)
00019 #define HAVE_SYSINFO 1
00020 #endif
00021
00022
00023
00024 #ifdef HAVE_SYSINFO
00025 #include <sys/systeminfo.h>
00026 #endif
00027
00028 #if !defined(HAVE_GETHOSTNAME)
00029 #define HAVE_GETHOSTNAME
00030 #include "sokintrf.h"
00031 #endif
00032
00033 #ifdef WIN32
00034 char *winver ();
00035 #endif
00036
00037 #include "timer.hh"
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <time.h>
00041 #include <math.h>
00042
00043 CMS_DIAGNOSTICS_INFO::CMS_DIAGNOSTICS_INFO ()
00044 {
00045 last_writer_dpi = NULL;
00046 last_reader_dpi = NULL;
00047 dpis = NULL;
00048 }
00049
00050 CMS_DIAGNOSTICS_INFO::~CMS_DIAGNOSTICS_INFO ()
00051 {
00052 last_writer_dpi = NULL;
00053 last_reader_dpi = NULL;
00054 if (NULL != dpis)
00055 {
00056 delete dpis;
00057 dpis = NULL;
00058 }
00059 }
00060
00061 CMS_DIAG_PROC_INFO *
00062 CMS::get_diag_proc_info ()
00063 {
00064 return dpi;
00065 }
00066
00067 void
00068 CMS::set_diag_proc_info (CMS_DIAG_PROC_INFO * _dpi)
00069 {
00070 dpi = _dpi;
00071 }
00072
00073
00074 double cmsdiag_timebias = 0.0;
00075 int cmsdiag_timebias_set = 0;
00076
00077 void
00078 CMS::setup_diag_proc_info ()
00079 {
00080 first_diag_store = 1;
00081 if (NULL == dpi)
00082 {
00083 dpi = new CMS_DIAG_PROC_INFO ();
00084 }
00085 strncpy (dpi->name, ProcessName, 16);
00086 int sysinfo_len = 0;
00087 memset (dpi->host_sysinfo, 0, 32);
00088 #ifdef HAVE_GETHOSTNAME
00089 #ifdef WIN32
00090 load_socket_interface ();
00091 #endif
00092 gethostname (dpi->host_sysinfo, 31);
00093 sysinfo_len += strlen (dpi->host_sysinfo);
00094 dpi->host_sysinfo[sysinfo_len++] = ',';
00095 dpi->host_sysinfo[sysinfo_len++] = ' ';
00096 #endif
00097
00098 #ifdef WIN32
00099 char *wvptr = winver ();
00100 if (NULL != wvptr)
00101 {
00102 strncpy (dpi->host_sysinfo + sysinfo_len, wvptr, 31 - sysinfo_len);
00103 sysinfo_len += strlen (dpi->host_sysinfo + sysinfo_len);
00104 }
00105 #endif
00106 #ifdef HAVE_SYSINFO
00107 if (sysinfo_len < 31)
00108 {
00109 sysinfo (SI_SYSNAME, dpi->host_sysinfo + sysinfo_len, 31 - sysinfo_len);
00110 sysinfo_len += strlen (dpi->host_sysinfo + sysinfo_len);
00111 }
00112 if (sysinfo_len < 31)
00113 {
00114 dpi->host_sysinfo[sysinfo_len++] = ' ';
00115 sysinfo (SI_RELEASE, dpi->host_sysinfo + sysinfo_len, 31 - sysinfo_len);
00116 sysinfo_len += strlen (dpi->host_sysinfo + sysinfo_len);
00117 }
00118 if (sysinfo_len < 31)
00119 {
00120 dpi->host_sysinfo[sysinfo_len++] = ',';
00121 sysinfo (SI_PLATFORM, dpi->host_sysinfo + sysinfo_len,
00122 31 - sysinfo_len);
00123 }
00124 #endif
00125 #ifdef VXWORKS
00126 if (sysinfo_len < 31)
00127 {
00128 char *modelname = sysModel ();
00129 if (NULL != modelname)
00130 {
00131 strncpy (dpi->host_sysinfo + sysinfo_len, modelname,
00132 31 - sysinfo_len);
00133 sysinfo_len += strlen (modelname);
00134 dpi->host_sysinfo[31] = 0;
00135 }
00136 }
00137 if (sysinfo_len < 31)
00138 {
00139 dpi->host_sysinfo[sysinfo_len++] = ',';
00140 }
00141 if (sysinfo_len < 31)
00142 {
00143 char *BspRevname = "VxWorks";
00144 if (NULL != BspRevname)
00145 {
00146 strncpy (dpi->host_sysinfo + sysinfo_len, BspRevname,
00147 31 - sysinfo_len);
00148 sysinfo_len += strlen (BspRevname);
00149 dpi->host_sysinfo[31] = 0;
00150 }
00151 }
00152 #endif
00153
00154
00155
00156 if (rcs_minor_version_number < 100)
00157 {
00158 dpi->rcslib_ver =
00159 (rcs_major_version_number + (rcs_minor_version_number * 1e-2));
00160 }
00161 else
00162 {
00163 dpi->rcslib_ver =
00164 (rcs_major_version_number + (rcs_minor_version_number * 1e-3));
00165 }
00166
00167 #ifdef WIN32
00168 dpi->pid = GetCurrentProcessId ();
00169 #else
00170 #ifdef VXWORKS
00171 dpi->pid = taskIdSelf ();
00172 #else
00173 dpi->pid = getpid ();
00174 #endif
00175 #endif
00176
00177 dpi->access_type = CMS_ZERO_ACCESS;
00178 dpi->msg_id = 0;
00179 dpi->msg_size = 0;
00180 dpi->msg_type = 0;
00181
00182 dpi->number_of_accesses = 0;
00183 dpi->number_of_new_messages = 0;
00184 dpi->bytes_moved = 0;
00185 dpi->last_access_time = 0;
00186 dpi->first_access_time = 0;
00187 dpi->max_difference = 0;
00188 dpi->min_difference = 0;
00189 first_diag_store = 1;
00190 #ifndef VXWORKS
00191 if (!cmsdiag_timebias_set)
00192 {
00193 cmsdiag_timebias_set = 1;
00194 time_t ttime = time (NULL);
00195 cmsdiag_timebias = floor (etime () - ttime);
00196 }
00197 #endif
00198 }
00199
00200 void
00201 CMS::calculate_and_store_diag_info (PHYSMEM_HANDLE * _handle,
00202 void *_user_data)
00203 {
00204 double cmsdiag_curtime = 0.0;
00205 if (NULL == dpi || _handle == NULL || !enable_diagnostics)
00206 {
00207 return;
00208 }
00209 long orig_offset = _handle->offset;
00210 CMS_DIAG_HEADER dh;
00211
00212 _handle->enable_byte_counting = 0;
00213 _handle->read (&dh, sizeof (CMS_DIAG_HEADER));
00214 if (connection_number == 0 && first_diag_store && dh.last_writer == 0)
00215 {
00216 dh.last_writer = -1;
00217 }
00218 if (connection_number == 0 && first_diag_store && dh.last_reader == 0)
00219 {
00220 dh.last_reader = -1;
00221 }
00222 if (internal_access_type == CMS_WRITE_ACCESS ||
00223 internal_access_type == CMS_WRITE_IF_READ_ACCESS)
00224 {
00225 dh.last_writer = connection_number;
00226 }
00227 else if (internal_access_type == CMS_READ_ACCESS)
00228 {
00229 dh.last_reader = connection_number;
00230 }
00231 _handle->write (&dh, sizeof (CMS_DIAG_HEADER));
00232 _handle->offset += sizeof (CMS_DIAG_HEADER);
00233 _handle->offset += (connection_number * sizeof (CMS_DIAG_PROC_INFO));
00234 char c;
00235 _handle->read (&c, 1);
00236 first_diag_store |= ((c != ProcessName[0] && c != dpi->name[0]) || c == 0);
00237 if (!first_diag_store)
00238 {
00239 _handle->read (dpi, sizeof (CMS_DIAG_PROC_INFO));
00240 }
00241 dpi->access_type = internal_access_type;
00242 dpi->msg_id = header.write_id;
00243 dpi->msg_size = header.in_buffer_size;
00244 if (internal_access_type == CMS_WRITE_ACCESS ||
00245 internal_access_type == CMS_WRITE_IF_READ_ACCESS)
00246 {
00247 if (NULL != _user_data)
00248 {
00249 dpi->msg_type = *((long *) _user_data);
00250 }
00251 }
00252 else
00253 {
00254 if (NULL != subdiv_data)
00255 {
00256 dpi->msg_type = *((long *) subdiv_data);
00257 }
00258 }
00259 if (!disable_diag_store)
00260 {
00261 dpi->number_of_accesses++;
00262 }
00263 if (dpi->number_of_accesses < 1)
00264 {
00265 dpi->number_of_accesses = 1;
00266 dpi->number_of_new_messages = 1;
00267 _handle->total_bytes_moved = 0;
00268 pre_op_total_bytes_moved = 0;
00269 first_diag_store = 1;
00270 }
00271 if (internal_access_type == CMS_WRITE_ACCESS ||
00272 internal_access_type == CMS_WRITE_IF_READ_ACCESS ||
00273 status == CMS_READ_OK)
00274 {
00275 dpi->number_of_new_messages++;
00276 if (dpi->number_of_new_messages < 1)
00277 {
00278 dpi->number_of_accesses = 1;
00279 dpi->number_of_new_messages = 1;
00280 _handle->total_bytes_moved = 0;
00281 pre_op_total_bytes_moved = 0;
00282 first_diag_store = 1;
00283 }
00284 }
00285 else if (disable_diag_store)
00286 {
00287 _handle->offset = orig_offset;
00288 first_diag_store = 0;
00289 _handle->enable_byte_counting = 1;
00290 return;
00291 }
00292
00293 dpi->bytes_moved += (_handle->total_bytes_moved - pre_op_total_bytes_moved);
00294 cmsdiag_curtime = etime () - cmsdiag_timebias;
00295 if (!first_diag_store)
00296 {
00297 double diff = cmsdiag_curtime - dpi->last_access_time;
00298 if (diff < 0.0)
00299 {
00300 dpi->bytes_moved = _handle->total_bytes_moved = 0.0;
00301 dpi->first_access_time = cmsdiag_curtime;
00302 dpi->last_access_time = cmsdiag_curtime;
00303 dpi->min_difference = 1e4;
00304 dpi->max_difference = 0.0;
00305 dpi->number_of_accesses = 0;
00306 dpi->number_of_new_messages = 0;
00307 _handle->total_bytes_moved = 0;
00308 pre_op_total_bytes_moved = 0;
00309 first_diag_store = 1;
00310 }
00311 if (!disable_diag_store)
00312 {
00313 if (diff < dpi->min_difference)
00314 {
00315 dpi->min_difference = diff;
00316 }
00317 }
00318 if (diff > dpi->max_difference)
00319 {
00320 dpi->max_difference = diff;
00321 }
00322 if (!disable_diag_store)
00323 {
00324 dpi->last_access_time = cmsdiag_curtime;
00325 }
00326 }
00327 else
00328 {
00329 dpi->bytes_moved = _handle->total_bytes_moved =
00330 (_handle->total_bytes_moved - pre_op_total_bytes_moved);
00331 dpi->first_access_time = cmsdiag_curtime;
00332 dpi->last_access_time = cmsdiag_curtime;
00333 dpi->min_difference = 1e4;
00334 dpi->max_difference = 0.0;
00335 dpi->number_of_accesses = 1;
00336 dpi->number_of_new_messages = 1;
00337 _handle->total_bytes_moved = 0.0;
00338 pre_op_total_bytes_moved = 0.0;
00339 }
00340 _handle->write (dpi, sizeof (CMS_DIAG_PROC_INFO));
00341 _handle->offset = orig_offset;
00342 first_diag_store = 0;
00343 _handle->enable_byte_counting = 1;
00344 }
00345
00346
00347 void
00348 CMS::internal_retrieve_diag_info (PHYSMEM_HANDLE * _handle, void *_user_data)
00349 {
00350 if (NULL == _handle || !enable_diagnostics)
00351 {
00352 return;
00353 }
00354 long orig_offset = _handle->offset;
00355 _handle->enable_byte_counting = 0;
00356 if (NULL == di)
00357 {
00358 di = new CMS_DIAGNOSTICS_INFO ();
00359 di->dpis = new RCS_LINKED_LIST ();
00360 }
00361 else
00362 {
00363 di->dpis->delete_members ();
00364 }
00365 _handle->read (di, sizeof (CMS_DIAG_HEADER));
00366 _handle->offset += sizeof (CMS_DIAG_HEADER);
00367
00368 for (int i = 0; i < total_connections; i++)
00369 {
00370 CMS_DIAG_PROC_INFO cms_dpi;
00371 _handle->read (&cms_dpi, sizeof (CMS_DIAG_PROC_INFO));
00372 _handle->offset += sizeof (CMS_DIAG_PROC_INFO);
00373 if (cms_dpi.name[0] != 0 || cms_dpi.number_of_accesses != 0)
00374 {
00375 di->dpis->store_at_tail (&cms_dpi, sizeof (CMS_DIAG_PROC_INFO), 1);
00376 if (i == di->last_writer)
00377 {
00378 di->last_writer_dpi =
00379 (CMS_DIAG_PROC_INFO *) di->dpis->get_tail ();
00380 }
00381 if (i == di->last_reader)
00382 {
00383 di->last_reader_dpi =
00384 (CMS_DIAG_PROC_INFO *) di->dpis->get_tail ();
00385 }
00386 }
00387 }
00388 _handle->offset = orig_offset;
00389 _handle->enable_byte_counting = 1;
00390
00391 }
00392
00393 CMS_DIAGNOSTICS_INFO *
00394 CMS::get_diagnostics_info ()
00395 {
00396 if (!enable_diagnostics)
00397 {
00398 return (NULL);
00399 }
00400
00401 internal_access_type = CMS_GET_DIAG_INFO_ACCESS;
00402 status = CMS_STATUS_NOT_SET;
00403 blocking_timeout = 0;
00404 main_access (data);
00405 return (di);
00406 }