#include "cmsdiag.hh"
#include "rcsversion.h"
#include <sys/types.h>
#include <unistd.h>
#include "timer.hh"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "linklist.hh"
#include "physmem.hh"
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); 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; dpi->msg_id = 0; dpi->msg_size = 0; dpi->msg_type = 0;
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; dpi->msg_id = header.write_id; 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); }
} else {
if (NULL != subdiv_data) {
dpi->msg_type = *((long *) subdiv_data); }
}
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);
}