/******************************************************************** * Description: cmsdiag.cc * * Derived from a work by Fred Proctor & Will Shackleford * * Author: * License: LGPL Version 2 * System: Linux * * Copyright (c) 2004 All rights reserved. * * Last change: ********************************************************************/ #include "cmsdiag.hh" #include "rcsversion.h" #include #include /* getpid() */ #include "timer.hh" // etime() #include // memset() #include // strncpy() #include // time_t, time() #include // floor() #include "linklist.hh" // LinkedList #include "physmem.hh" // PHYSMEM_HANDLE CMS_DIAGNOSTICS_INFO::CMS_DIAGNOSTICS_INFO() { last_writer_dpi = NULL; last_reader_dpi = NULL; dpis = NULL; } CMS_DIAGNOSTICS_INFO::~CMS_DIAGNOSTICS_INFO() { last_writer_dpi = NULL; last_reader_dpi = NULL; if (NULL != dpis) { delete dpis; dpis = NULL; } } CMS_DIAG_PROC_INFO *CMS::get_diag_proc_info() { return dpi; } void CMS::set_diag_proc_info(CMS_DIAG_PROC_INFO * _dpi) { dpi = _dpi; } double cmsdiag_timebias = 0.0; int cmsdiag_timebias_set = 0; void CMS::setup_diag_proc_info() { first_diag_store = 1; if (NULL == dpi) { dpi = new CMS_DIAG_PROC_INFO(); } strncpy(dpi->name, ProcessName, 16); // process name int sysinfo_len = 0; memset(dpi->host_sysinfo, 0, 32); gethostname(dpi->host_sysinfo, 31); sysinfo_len += strlen(dpi->host_sysinfo); dpi->host_sysinfo[sysinfo_len++] = ','; dpi->host_sysinfo[sysinfo_len++] = ' '; if (lib_minor_version < 100) { dpi->rcslib_ver = (lib_major_version + (lib_minor_version * 1e-2)); } else { dpi->rcslib_ver = (lib_major_version + (lib_minor_version * 1e-3)); } dpi->pid = getpid(); dpi->access_type = CMS_ZERO_ACCESS; // access type of last operation dpi->msg_id = 0; // id of the message written or at time of // read. dpi->msg_size = 0; // size of the message written or at time of // read. dpi->msg_type = 0; // id of the message written or at time of // read. dpi->number_of_accesses = 0; dpi->number_of_new_messages = 0; dpi->bytes_moved = 0; dpi->last_access_time = 0; dpi->first_access_time = 0; dpi->max_difference = 0; dpi->min_difference = 0; first_diag_store = 1; if (!cmsdiag_timebias_set) { cmsdiag_timebias_set = 1; time_t ttime = time(NULL); cmsdiag_timebias = floor(etime() - ttime); } } void CMS::calculate_and_store_diag_info(PHYSMEM_HANDLE * _handle, void *_user_data) { double cmsdiag_curtime = 0.0; if (NULL == dpi || _handle == NULL || !enable_diagnostics) { return; } long orig_offset = _handle->offset; CMS_DIAG_HEADER dh; _handle->enable_byte_counting = 0; _handle->read(&dh, sizeof(CMS_DIAG_HEADER)); if (connection_number == 0 && first_diag_store && dh.last_writer == 0) { dh.last_writer = -1; } if (connection_number == 0 && first_diag_store && dh.last_reader == 0) { dh.last_reader = -1; } if (internal_access_type == CMS_WRITE_ACCESS || internal_access_type == CMS_WRITE_IF_READ_ACCESS) { dh.last_writer = connection_number; } else if (internal_access_type == CMS_READ_ACCESS) { dh.last_reader = connection_number; } _handle->write(&dh, sizeof(CMS_DIAG_HEADER)); _handle->offset += sizeof(CMS_DIAG_HEADER); _handle->offset += (connection_number * sizeof(CMS_DIAG_PROC_INFO)); char c; _handle->read(&c, 1); first_diag_store |= ((c != ProcessName[0] && c != dpi->name[0]) || c == 0); if (!first_diag_store) { _handle->read(dpi, sizeof(CMS_DIAG_PROC_INFO)); } dpi->access_type = internal_access_type; // access type of last // operation dpi->msg_id = header.write_id; // id of the message written or at // time of read. dpi->msg_size = header.in_buffer_size; if (internal_access_type == CMS_WRITE_ACCESS || internal_access_type == CMS_WRITE_IF_READ_ACCESS) { if (NULL != _user_data) { dpi->msg_type = *((long *) _user_data); // id of the message // written or at time // of read. } } else { if (NULL != subdiv_data) { dpi->msg_type = *((long *) subdiv_data); // id of the message // written or at time // of read. } } if (!disable_diag_store) { dpi->number_of_accesses++; } if (dpi->number_of_accesses < 1) { dpi->number_of_accesses = 1; dpi->number_of_new_messages = 1; _handle->total_bytes_moved = 0; pre_op_total_bytes_moved = 0; first_diag_store = 1; } if (internal_access_type == CMS_WRITE_ACCESS || internal_access_type == CMS_WRITE_IF_READ_ACCESS || status == CMS_READ_OK) { dpi->number_of_new_messages++; if (dpi->number_of_new_messages < 1) { dpi->number_of_accesses = 1; dpi->number_of_new_messages = 1; _handle->total_bytes_moved = 0; pre_op_total_bytes_moved = 0; first_diag_store = 1; } } else if (disable_diag_store) { _handle->offset = orig_offset; first_diag_store = 0; _handle->enable_byte_counting = 1; return; } dpi->bytes_moved += (_handle->total_bytes_moved - pre_op_total_bytes_moved); cmsdiag_curtime = etime() - cmsdiag_timebias; if (!first_diag_store) { double diff = cmsdiag_curtime - dpi->last_access_time; if (diff < 0.0) { dpi->bytes_moved = _handle->total_bytes_moved = 0.0; dpi->first_access_time = cmsdiag_curtime; dpi->last_access_time = cmsdiag_curtime; dpi->min_difference = 1e4; dpi->max_difference = 0.0; dpi->number_of_accesses = 0; dpi->number_of_new_messages = 0; _handle->total_bytes_moved = 0; pre_op_total_bytes_moved = 0; first_diag_store = 1; } if (!disable_diag_store) { if (diff < dpi->min_difference) { dpi->min_difference = diff; } } if (diff > dpi->max_difference) { dpi->max_difference = diff; } if (!disable_diag_store) { dpi->last_access_time = cmsdiag_curtime; } } else { dpi->bytes_moved = _handle->total_bytes_moved = (_handle->total_bytes_moved - pre_op_total_bytes_moved); dpi->first_access_time = cmsdiag_curtime; dpi->last_access_time = cmsdiag_curtime; dpi->min_difference = 1e4; dpi->max_difference = 0.0; dpi->number_of_accesses = 1; dpi->number_of_new_messages = 1; _handle->total_bytes_moved = 0.0; pre_op_total_bytes_moved = 0.0; } _handle->write(dpi, sizeof(CMS_DIAG_PROC_INFO)); _handle->offset = orig_offset; first_diag_store = 0; _handle->enable_byte_counting = 1; } void CMS::internal_retrieve_diag_info(PHYSMEM_HANDLE * _handle, void *_user_data) { if (NULL == _handle || !enable_diagnostics) { return; } long orig_offset = _handle->offset; _handle->enable_byte_counting = 0; if (NULL == di) { di = new CMS_DIAGNOSTICS_INFO(); di->dpis = new LinkedList(); } else { di->dpis->delete_members(); } _handle->read(di, sizeof(CMS_DIAG_HEADER)); _handle->offset += sizeof(CMS_DIAG_HEADER); for (int i = 0; i < total_connections; i++) { CMS_DIAG_PROC_INFO cms_dpi; _handle->read(&cms_dpi, sizeof(CMS_DIAG_PROC_INFO)); _handle->offset += sizeof(CMS_DIAG_PROC_INFO); if (cms_dpi.name[0] != 0 || cms_dpi.number_of_accesses != 0) { di->dpis->store_at_tail(&cms_dpi, sizeof(CMS_DIAG_PROC_INFO), 1); if (i == di->last_writer) { di->last_writer_dpi = (CMS_DIAG_PROC_INFO *) di->dpis->get_tail(); } if (i == di->last_reader) { di->last_reader_dpi = (CMS_DIAG_PROC_INFO *) di->dpis->get_tail(); } } } _handle->offset = orig_offset; _handle->enable_byte_counting = 1; } CMS_DIAGNOSTICS_INFO *CMS::get_diagnostics_info() { if (!enable_diagnostics) { return (NULL); } internal_access_type = CMS_GET_DIAG_INFO_ACCESS; status = CMS_STATUS_NOT_SET; blocking_timeout = 0; main_access(data); return (di); }