source: trunk/src/testing/QUANTA/src/QUANTAnet_perfMonitor_c.cxx @ 4

Revision 4, 9.4 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/******************************************************************************
2 * QUANTA - A toolkit for High Performance Data Sharing
3 * Copyright (C) 2003 Electronic Visualization Laboratory, 
4 * University of Illinois at Chicago
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above
14 *    copyright notice, this list of conditions and the following disclaimer
15 *    in the documentation and/or other materials provided with the distribution.
16 *  * Neither the name of the University of Illinois at Chicago nor
17 *    the names of its contributors may be used to endorse or promote
18 *    products derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Direct questions, comments etc about Quanta to cavern@evl.uic.edu
33 *****************************************************************************/
34
35
36#ifdef QUANTA_USE_PTHREADS
37#include <pthread.h>
38#endif
39       
40#include <errno.h>
41#include <string.h>
42
43#include "QUANTAnet_perfClient_c.hxx"
44#include "QUANTAnet_perfMonitor_c.hxx"
45
46const int QUANTAnet_perfMonitor_c::FAILED = 0;
47const int QUANTAnet_perfMonitor_c::OK = 1;
48
49const int _DEFAULT_PERF_BUFFER_SIZE = 1024;
50const int _STREAM_INFO_SIZE = 256;
51
52QUANTAnet_perfMonitor_c::QUANTAnet_perfMonitor_c()
53{
54    resultantStats = new char[_DEFAULT_PERF_BUFFER_SIZE];
55    resultantStats[0] = '\0';
56    selfIp = new char[_STREAM_INFO_SIZE];
57    remoteIp = new char[_STREAM_INFO_SIZE];
58    aClient = NULL;     
59}
60
61// css: The copy constructor is required due to operations like
62// QUANTAnet_udp_c::clone() which copy one class to another. By default, C++
63// only does a shallow copy. This means that the pointers are copied rather
64// than the values they contain. As a result, the cloned object can easily
65// lead to memory corruption. This copy constructor initializes the new
66// object and copies values from the original one.
67QUANTAnet_perfMonitor_c::QUANTAnet_perfMonitor_c(const QUANTAnet_perfMonitor_c& original)
68{
69  resultantStats = new char[_DEFAULT_PERF_BUFFER_SIZE];
70  resultantStats[0] = '\0';
71  selfIp = new char[_STREAM_INFO_SIZE];
72  remoteIp = new char[_STREAM_INFO_SIZE];
73
74  // With everything allocated, now do a deep copy.
75  aClient = original.aClient;
76  strncpy(selfIp, original.selfIp, _STREAM_INFO_SIZE);
77  strncpy(remoteIp, original.remoteIp, _STREAM_INFO_SIZE);
78}
79
80QUANTAnet_perfMonitor_c::~QUANTAnet_perfMonitor_c()
81{
82  if (resultantStats)
83    delete[] resultantStats;
84  if (selfIp)
85    delete[] selfIp;
86  if (remoteIp)
87    delete[] remoteIp;
88  if (aClient)
89    delete aClient;
90}
91
92void QUANTAnet_perfMonitor_c::setIPs(const char* _selfIp, const char* _remoteIp)
93{
94  if (_selfIp)
95    strncpy(this->selfIp, _selfIp, _STREAM_INFO_SIZE);
96
97  if (_remoteIp)
98    strncpy(this->remoteIp, _remoteIp, _STREAM_INFO_SIZE);
99}
100
101void QUANTAnet_perfMonitor_c::setPorts(int _selfPort, int _remotePort)
102{
103    selfPort = _selfPort;
104    remotePort = _remotePort;   
105}
106
107void QUANTAnet_perfMonitor_c::showStats(char* streamInfo, char* comment)
108{
109    //update the resultant buffer with the calculated information
110    updateStats(streamInfo, comment);
111    printf("\n%s\n", resultantStats);   
112}
113
114int QUANTAnet_perfMonitor_c::logStats(char* streamInfo, char* comment, FILE* filePtr)
115{
116        if (filePtr) {
117                //update the resultant buffer with the calculated information
118                updateStats(streamInfo, comment);
119 
120                if ((fprintf(filePtr, "%s\n", resultantStats)) != (strlen(resultantStats) + 1)) {
121                        printf("\nWarning: Error writing to logfile - data may be truncated or  not written at all\n");
122                        return QUANTAnet_perfMonitor_c::FAILED;
123                }   
124                fflush(filePtr);
125        }
126        else {
127            printf("File pointer must be given to use logStats.\n");
128                return QUANTAnet_perfMonitor_c::FAILED;
129        }
130    return QUANTAnet_perfMonitor_c::OK;
131}
132
133int QUANTAnet_perfMonitor_c::initSendStats(const char* monitorClientIP, int port)
134{
135        if (monitorClientIP) {
136                if (aClient) {
137                        delete aClient;
138                        aClient = NULL;// close current connection first.
139                }
140                aClient = new QUANTAnet_perfDaemonClient_c;
141                if (aClient == NULL) {
142                    printf("Cannot create perfDaemonClient.\n");
143                        return QUANTAnet_perfMonitor_c::FAILED;
144                }
145
146                if (aClient->connectToServer(monitorClientIP, port) == QUANTAnet_perfDaemonClient_c::FAILED) {
147                        printf("\nCannot connect to perf_daemon\n");
148                delete aClient;       
149                        aClient = NULL;
150                        return QUANTAnet_perfMonitor_c::FAILED;
151                }
152                int len = SEND_STAT_CLIENT_LENGTH + 1; // including terminating null char
153                if (aClient->write(SEND_STAT_CLIENT, &len) != QUANTAnet_perfDaemonClient_c::OK) {
154                    printf("Cannot connect to perf_daemon\n");
155                        delete aClient;
156                        aClient = NULL;
157                        return QUANTAnet_perfMonitor_c::FAILED;
158                }
159        }
160        else {
161            printf("Invalid ip address for perf_daemon is given. Please verify the address again.\n");
162                return QUANTAnet_perfMonitor_c::FAILED;
163        }
164    return QUANTAnet_perfMonitor_c::OK;
165}
166
167int QUANTAnet_perfMonitor_c::sendStats(char* streamInfo, char* comment)
168{
169        if (aClient == NULL) {
170                printf("PerfDaemonClient is not initialized. No data will be sent to perf_daemon\n");
171            return QUANTAnet_perfMonitor_c::FAILED;
172        }
173
174        //update the resultant buffer with the calculated information
175        updateStats(streamInfo, comment);
176
177        int nbytes = strlen(resultantStats) + 1;
178
179        //transmitting data to perfdaemon   
180        int status = aClient->write(resultantStats, &nbytes);
181        if (status != QUANTAnet_perfDaemonClient_c::OK) {
182                aClient->showStatus(status, nbytes);
183                delete aClient;
184                aClient = NULL;
185                return QUANTAnet_perfMonitor_c::FAILED;
186        }
187
188    return QUANTAnet_perfMonitor_c::OK;
189}
190
191void QUANTAnet_perfMonitor_c::exitSendStats()
192{
193        if (aClient) {
194                delete aClient;
195                aClient = NULL;
196        }
197}
198
199void QUANTAnet_perfMonitor_c::updateStats(char* streamInfo, char* comment)
200{
201  //update the resultant stats buffer
202  if (resultantStats) {
203    char *tempStreamInfo, *tempComment;
204    char tempMsg[] = "NULL";
205
206    tempComment = (comment == NULL) ? tempMsg : comment;       
207    tempStreamInfo = (streamInfo == NULL) ? tempMsg : streamInfo;
208
209    // css: When copying into the resultantStats buffer, try to avoid a
210    // buffer overflow by limiting the operation with snprintf().
211#ifdef WIN32
212    _snprintf(resultantStats, _DEFAULT_PERF_BUFFER_SIZE,
213              "TIME=%lf SELF_IP=%s REMOTE_IP=%s SELF_PORT=%d " \
214              "REMOTE_PORT=%d STREAM_INFO=%s COMMENT=%s MIN_LAT=%lf " \
215              "AVG_LAT=%lf MAX_LAT=%lf INST_LAT=%lf STAL=%lf JITTER=%lf " \
216              "MIN_IMD=%lf AVG_IMD=%lf MAX_IMD=%lf INST_IMD=%lf " \
217              "AVG_RBW=%lf INST_RBW=%lf AVG_SBW=%lf INST_SBW=%lf " \
218              "STAB=%lf BURSTINESS=%lf TOTAL_READ=%d TOTAL_SENT=%d " \
219              "PACKETS_READ=%ld PACKETS_SENT=%ld", getTimeInSecs(),
220              selfIp, remoteIp, selfPort, remotePort, tempStreamInfo,
221              tempComment,  getMinLatency(), getAverageLatency(),
222              getMaxLatency(), getInstantLatency(), getSTALatency(),
223              getJitter(),  getMinInterMesgDelay(),
224              getAverageInterMesgDelay(), getMaxInterMesgDelay(),
225              getInstantInterMesgDelay(), getAverageReceiveBandwidth(),
226              getInstantReceiveBandwidth(),  getAverageSendBandwidth(),
227              getInstantSendBandwidth(), getSTABandwidth(),
228              getBurstiness(), getTotalDataRead(),  getTotalDataSent(),
229              getPacketsRead(), getPacketsSent());
230#else /* WIN32 */
231    snprintf(resultantStats, _DEFAULT_PERF_BUFFER_SIZE,
232             "TIME=%lf SELF_IP=%s REMOTE_IP=%s SELF_PORT=%d " \
233             "REMOTE_PORT=%d STREAM_INFO=%s COMMENT=%s MIN_LAT=%lf " \
234             "AVG_LAT=%lf MAX_LAT=%lf INST_LAT=%lf STAL=%lf JITTER=%lf " \
235             "MIN_IMD=%lf AVG_IMD=%lf MAX_IMD=%lf INST_IMD=%lf " \
236             "AVG_RBW=%lf INST_RBW=%lf AVG_SBW=%lf INST_SBW=%lf " \
237             "STAB=%lf BURSTINESS=%lf TOTAL_READ=%d TOTAL_SENT=%d " \
238             "PACKETS_READ=%ld PACKETS_SENT=%ld", getTimeInSecs(),
239             selfIp, remoteIp, selfPort, remotePort, tempStreamInfo,
240             tempComment,  getMinLatency(), getAverageLatency(),
241             getMaxLatency(), getInstantLatency(), getSTALatency(),
242             getJitter(),  getMinInterMesgDelay(),
243             getAverageInterMesgDelay(), getMaxInterMesgDelay(),
244             getInstantInterMesgDelay(), getAverageReceiveBandwidth(),
245             getInstantReceiveBandwidth(),  getAverageSendBandwidth(),
246             getInstantSendBandwidth(), getSTABandwidth(),
247             getBurstiness(), getTotalDataRead(),  getTotalDataSent(),
248             getPacketsRead(), getPacketsSent());
249#endif /* WIN32 */
250  }
251}
252
253
254
255
256
257
258
259
260
261
262
Note: See TracBrowser for help on using the repository browser.