~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/libs/uti/sge_monitor.h

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _SGE_MONITOR_H
 
2
#define _SGE_MONITOR_H
 
3
 
 
4
/*___INFO__MARK_BEGIN__*/
 
5
/*************************************************************************
 
6
 * 
 
7
 *  The Contents of this file are made available subject to the terms of
 
8
 *  the Sun Industry Standards Source License Version 1.2
 
9
 * 
 
10
 *  Sun Microsystems Inc., March, 2001
 
11
 * 
 
12
 * 
 
13
 *  Sun Industry Standards Source License Version 1.2
 
14
 *  =================================================
 
15
 *  The contents of this file are subject to the Sun Industry Standards
 
16
 *  Source License Version 1.2 (the "License"); You may not use this file
 
17
 *  except in compliance with the License. You may obtain a copy of the
 
18
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
19
 * 
 
20
 *  Software provided under this License is provided on an "AS IS" basis,
 
21
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
22
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
23
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
24
 *  See the License for the specific provisions governing your rights and
 
25
 *  obligations concerning the Software.
 
26
 * 
 
27
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
28
 * 
 
29
 *   Copyright: 2003 by Sun Microsystems, Inc.
 
30
 * 
 
31
 *   All Rights Reserved.
 
32
 * 
 
33
 ************************************************************************/
 
34
/*___INFO__MARK_END__*/
 
35
 
 
36
#include <sys/time.h>
 
37
 
 
38
#include "basis_types.h"
 
39
#include "uti/sge_dstring.h"
 
40
 
 
41
/**
 
42
 * Monitoring functionality:
 
43
 * -------------------------
 
44
 *
 
45
 * - qping health monitoring
 
46
 *
 
47
 * - keeping statistics on what is done during a thread loop
 
48
 *
 
49
 * - outputing the statistics information via message file or
 
50
 *   qping
 
51
 *
 
52
 *
 
53
 * Monitoring Usage:
 
54
 * -----------------
 
55
 *
 
56
 * do a normal data definition, call init and free, when you are done.
 
57
 * You have to call MONITOR_IDLE_TIME and sge_monitor_output. After that
 
58
 * everything is up to you to design...
 
59
 *
 
60
 * -----start thread --------------
 
61
 *    monitoring_t monitor;
 
62
 *   
 
63
 *    sge_monitor_init(&monitor, "THREAD NAME", <EXTENSION>, <WARNING>, <ERROR>);
 
64
 *   
 
65
 *    <thread loop> {
 
66
 *       
 
67
 *       MONITOR_IDLE_TIME(<wait for something>,(&monitor), monitor_time);
 
68
 *   
 
69
 *      < do your stuff and monitoring >
 
70
 *   
 
71
 *       sge_monitor_output(&monitor);
 
72
 *    }
 
73
 *    sge_monitor_free(&monitor);
 
74
 * ------end thread----------------
 
75
 *
 
76
 * Improtant:
 
77
 * ----------
 
78
 *  The call to MONITOR_IDLE_TIME has to be the first one after the thread loop otherwise
 
79
 *  certain parts of the monitoring structure are not correctly initilized.
 
80
 *
 
81
 * General statistic methods:
 
82
 * --------------------------
 
83
 *
 
84
 * - MONITOR_IDLE_TIME    : counts idle time, very important, nothing works without it
 
85
 * - MONITOR_WAIT_TIME    : counts wait time (wait for a lock usually)
 
86
 * - MONITOR_MESSAGES     : counts how many times the thread loop is executed
 
87
 * - MONITOR_MESSAGES_OUT : counts how many messages are send
 
88
 *
 
89
 * GDI statistics methods:
 
90
 * -----------------------
 
91
 *
 
92
 * - MONITOR_GDI  : counts GDI requests
 
93
 * - MONITOR_ACK  : counts ACKs
 
94
 * - MONITOR_LOAD : counts reports
 
95
 */
 
96
 
 
97
 
 
98
/**
 
99
 * qping thread warning times in seconds
 
100
 */
 
101
typedef enum {
 
102
   NO_WARNING    = 0,
 
103
   EMT_WARNING   = 10,
 
104
   TET_WARNING   = 30,
 
105
   MT_WARNING    = 10,
 
106
   ST_WARNING    = 0,  /* no timeout for this thread */
 
107
   EXECD_WARNING = 10,
 
108
   SCT_WARNING   = 20
 
109
}thread_warning_t;
 
110
 
 
111
/* EB: TODO: ST: ??? */
 
112
 
 
113
/**
 
114
 * qping thread error times in seconds
 
115
 **/
 
116
typedef enum {
 
117
   NO_ERROR    = 0,
 
118
   EMT_ERROR   = 600,
 
119
   TET_ERROR   = 600,
 
120
   MT_ERROR    = 600,
 
121
   ST_ERROR    = 0,   /* no timeout for this thread */
 
122
   EXECD_ERROR = 600,
 
123
   SCT_ERROR   = 600   
 
124
}thread_error_t;
 
125
 
 
126
/**
 
127
 * This function definition is the prototyp for the output function of a data
 
128
 * extension
 
129
 */
 
130
typedef void (*extension_output)(
 
131
   dstring *info_message,    /* target memory buffer*/
 
132
   void *monitor_extension,  /* contains the monitor extension structur */
 
133
   double time               /* length of the time inteval */
 
134
);
 
135
 
 
136
/**
 
137
 * This enum identifies all available extensions
 
138
 */
 
139
typedef enum {
 
140
   NONE_EXT = -1,
 
141
   GDI_EXT = 0,         /* GDI = request processing thread */
 
142
   EDT_EXT = 1,         /* EDT = event delivery thread */
 
143
   TET_EXT = 2,         /* TET = timed event thread */
 
144
   LIS_EXT = 3,         /* LIS = listener thread */
 
145
   SCH_EXT = 4          /* SCH = scheduler thread */
 
146
}extension_t;
 
147
 
 
148
/**
 
149
 * the monitoring data structure
 
150
 */
 
151
typedef struct {
 
152
   /*--- init data ------------*/
 
153
   const char *thread_name;
 
154
   u_long32    monitor_time;        /* stores the time interval for the mesuring run */
 
155
   bool        log_monitor_mes;     /* if true, it logs the monitoring info into the message file */
 
156
   /*--- output data ----------*/
 
157
   dstring *output_line1;
 
158
   dstring *output_line2;
 
159
   dstring *work_line;
 
160
   int  pos;                        /* position (line) in the qping output structure (kind of thread id) */
 
161
   /*--- work data ------------*/
 
162
   struct timeval now;              /* start time of mesurement */
 
163
   bool        output;              /* if true, triggers qping / message output */
 
164
   u_long32    message_in_count;
 
165
   u_long32    message_out_count;
 
166
   double      idle;                /* idle time*/
 
167
   double      wait;                /* wait time*/
 
168
   /*--- extension data -------*/
 
169
   extension_t       ext_type; 
 
170
   void             *ext_data;
 
171
   u_long32          ext_data_size;
 
172
   extension_output  ext_output; 
 
173
} monitoring_t;
 
174
 
 
175
void sge_monitor_init(monitoring_t *monitor, const char *thread_name, extension_t ext, 
 
176
                 thread_warning_t warning_timeout, thread_error_t error_timeout);
 
177
void sge_monitor_free(monitoring_t *monitor);
 
178
u_long32 sge_monitor_status(char **info_message, u_long32 monitor_time);
 
179
void sge_set_last_wait_time(monitoring_t *monitor, struct timeval after); 
 
180
 
 
181
void sge_monitor_output(monitoring_t *monitor); 
 
182
void sge_monitor_reset(monitoring_t *monitor);
 
183
 
 
184
 
 
185
/****************
 
186
 * MACRO section
 
187
 ****************/
 
188
 
 
189
#define MONITOR_IDLE_TIME(execute, monitor, output_time, is_log)    { \
 
190
                                 struct timeval before;  \
 
191
                                 gettimeofday(&before, NULL); \
 
192
                                 sge_set_last_wait_time((monitor), before); \
 
193
                                 if (output_time > 0) { \
 
194
                                    struct timeval before;  \
 
195
                                    struct timeval after; \
 
196
                                    double time; \
 
197
                                    \
 
198
                                    (monitor)->monitor_time = output_time; \
 
199
                                    (monitor)->log_monitor_mes = is_log; \
 
200
                                    gettimeofday(&before, NULL); \
 
201
                                    if ((monitor)->now.tv_sec == 0) { \
 
202
                                       (monitor)->now = before; \
 
203
                                    } \
 
204
                                    execute; \
 
205
                                    gettimeofday(&after, NULL);  \
 
206
                                    (monitor)->output = ((after.tv_sec-(monitor)->now.tv_sec) >= (monitor)->monitor_time)?true:false; \
 
207
                                    time = after.tv_usec - before.tv_usec; \
 
208
                                    time = after.tv_sec - before.tv_sec + (time/1000000); \
 
209
                                    (monitor)->idle += time; \
 
210
                                 } \
 
211
                                 else { \
 
212
                                    execute; \
 
213
                                 } \
 
214
                              } \
 
215
 
 
216
/**
 
217
 * This might pose a problem if it is called with another makro. 
 
218
 *
 
219
 * TODO: it should be customized for read/write locks.
 
220
 */
 
221
#define MONITOR_WAIT_TIME(execute, monitor)    if (((monitor) != NULL) && ((monitor)->monitor_time > 0)){ \
 
222
                                    struct timeval before;  \
 
223
                                    struct timeval after; \
 
224
                                    double time; \
 
225
                                    \
 
226
                                    gettimeofday(&before, NULL); \
 
227
                                    execute; \
 
228
                                    gettimeofday(&after, NULL);  \
 
229
                                    time = after.tv_usec - before.tv_usec; \
 
230
                                    time = after.tv_sec - before.tv_sec + (time/1000000); \
 
231
                                    (monitor)->wait += time; \
 
232
                                 } \
 
233
                                 else { \
 
234
                                    execute; \
 
235
                                 } \
 
236
 
 
237
#define MONITOR_MESSAGES(monitor) if ((monitor != NULL) && ((monitor)->monitor_time > 0)) (monitor)->message_in_count++
 
238
 
 
239
#define MONITOR_MESSAGES_OUT(monitor) if (((monitor) != NULL) && ((monitor)->monitor_time > 0)) (monitor)->message_out_count++
 
240
 
 
241
/*--------------------------------*/
 
242
/*   EXTENSION SECTION            */
 
243
/*--------------------------------*/
 
244
 
 
245
/**
 
246
 * What you need to do to create a new extension:
 
247
 *
 
248
 * - create a new extension_t in the enum
 
249
 * - define a extension data structure
 
250
 * - modifiy the sge_monitor_init method to handle the new extension type
 
251
 *   Example:
 
252
 *     case GDI_EXT :
 
253
 *          monitor->ext_data_size = sizeof(m_gdi_t);
 
254
 *          monitor->ext_data = malloc(sizeof(m_gdi_t));
 
255
 *          monitor->ext_output = &ext_gdi_output;
 
256
 *       break;
 
257
 *
 
258
 * - write the extension output function
 
259
 * - write the measurement makros
 
260
 * - remember, that the entire extension structure is reset to 0 after the data is printed
 
261
 *
 
262
 **/
 
263
 
 
264
 
 
265
/* scheduler thread extensions */
 
266
 
 
267
typedef struct {
 
268
   u_long32    dummy;    /* unused */
 
269
} m_sch_t;
 
270
 
 
271
/* GDI message thread extensions */
 
272
 
 
273
typedef struct {
 
274
   u_long32    gdi_add_count;    /* counts the gdi add requests */
 
275
   u_long32    gdi_mod_count;    /* counts the gdi mod requests */
 
276
   u_long32    gdi_get_count;    /* counts the gdi get requests */
 
277
   u_long32    gdi_del_count;    /* counts teh gdi del requests */
 
278
   u_long32    gdi_cp_count;     /* counts the gdi cp requests */
 
279
   u_long32    gdi_trig_count;   /* counts the gdi trig requests */
 
280
   u_long32    gdi_perm_count;   /* counts the gdi perm requests */
 
281
   u_long32    gdi_replace_count;   /* counts the gdi perm requests */
 
282
 
 
283
   u_long32    eload_count; /* counts the execd load reports */
 
284
   u_long32    econf_count; /* counts the execd conf version requests */
 
285
   u_long32    ejob_count;  /* counts the execd job reports */
 
286
   u_long32    eproc_count; /* counts the execd processor reports */
 
287
   u_long32    eack_count;  /* counts the execd acks */
 
288
 
 
289
   u_long32    queue_length;     /* worker queue length */
 
290
} m_gdi_t;
 
291
 
 
292
#define MONITOR_GDI_ADD(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_add_count++
 
293
#define MONITOR_GDI_GET(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_get_count++
 
294
#define MONITOR_GDI_MOD(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_mod_count++
 
295
#define MONITOR_GDI_DEL(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_del_count++
 
296
#define MONITOR_GDI_CP(monitor)     if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_cp_count++
 
297
#define MONITOR_GDI_TRIG(monitor)   if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_trig_count++
 
298
#define MONITOR_GDI_PERM(monitor)   if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_perm_count++
 
299
#define MONITOR_GDI_REPLACE(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_replace_count++
 
300
 
 
301
#define MONITOR_ACK(monitor)     if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->ack_count++
 
302
 
 
303
#define MONITOR_ELOAD(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->eload_count++
 
304
#define MONITOR_ECONF(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->econf_count++
 
305
#define MONITOR_EJOB(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->ejob_count++
 
306
#define MONITOR_EPROC(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->eproc_count++
 
307
#define MONITOR_EACK(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->eack_count++
 
308
 
 
309
#define MONITOR_SET_QLEN(monitor, qlen)    if ((monitor) != NULL && (monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->queue_length = (qlen)
 
310
 
 
311
/* listener extension */
 
312
typedef struct {
 
313
   u_long32    inc_gdi; /* incoming GDI requests */
 
314
   u_long32    inc_ack; /* ack requests */
 
315
   u_long32    inc_ece; /* event client exits */
 
316
   u_long32    inc_rep; /* report request */
 
317
} m_lis_t;
 
318
 
 
319
#define MONITOR_INC_GDI(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == LIS_EXT)) ((m_lis_t*)(monitor->ext_data))->inc_gdi++
 
320
#define MONITOR_INC_ACK(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == LIS_EXT)) ((m_lis_t*)(monitor->ext_data))->inc_ack++
 
321
#define MONITOR_INC_ECE(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == LIS_EXT)) ((m_lis_t*)(monitor->ext_data))->inc_ece++
 
322
#define MONITOR_INC_REP(monitor)    if ((monitor->monitor_time > 0) && (monitor->ext_type == LIS_EXT)) ((m_lis_t*)(monitor->ext_data))->inc_rep++
 
323
 
 
324
/* event master thread extension */
 
325
 
 
326
typedef struct {
 
327
   u_long32   count;                /* counts the number of runs */
 
328
   u_long32   client_count;         /* connected event clients */
 
329
   u_long32   mod_client_count;     /* event client modifications */
 
330
   u_long32   ack_count;            /* nr of acknowledges */
 
331
   u_long32   new_event_count;      /* newly added events */
 
332
   u_long32   added_event_count;    /* nr of events added to the event clients */
 
333
   u_long32   skip_event_count;     /* nr of events ignored, no client has a subscription */
 
334
   u_long32   blocked_client_count; /* nr of event clients blocked during send */
 
335
   u_long32   busy_client_count;    /* nr of event clients busy during send */
 
336
}m_edt_t;
 
337
 
 
338
#define MONITOR_CLIENT_COUNT(monitor, inc)  if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
339
                                               ((m_edt_t*) (monitor->ext_data))->client_count += inc
 
340
 
 
341
#define MONITOR_EDT_COUNT(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
342
                                    ((m_edt_t*) (monitor->ext_data))->count++
 
343
 
 
344
#define MONITOR_EDT_MOD(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
345
                                    ((m_edt_t*) (monitor->ext_data))->mod_client_count++
 
346
 
 
347
#define MONITOR_EDT_ACK(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
348
                                    ((m_edt_t*)(monitor->ext_data))->ack_count++
 
349
 
 
350
#define MONITOR_EDT_NEW(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
351
                                    ((m_edt_t*)(monitor->ext_data))->new_event_count++
 
352
 
 
353
#define MONITOR_EDT_ADDED(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
354
                                    ((m_edt_t*)(monitor->ext_data))->added_event_count++
 
355
 
 
356
#define MONITOR_EDT_SKIP(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
357
                                    ((m_edt_t*)(monitor->ext_data))->skip_event_count++
 
358
 
 
359
#define MONITOR_EDT_BLOCKED(monitor)  if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
360
                                    ((m_edt_t*)(monitor->ext_data))->blocked_client_count++
 
361
 
 
362
#define MONITOR_EDT_BUSY(monitor)  if ((monitor->monitor_time > 0) && (monitor->ext_type == EDT_EXT)) \
 
363
                                    ((m_edt_t*)(monitor->ext_data))->busy_client_count++
 
364
 
 
365
/* timed event thread extension */
 
366
 
 
367
typedef struct {
 
368
   u_long32   count;         /* counts the number of runs */
 
369
   u_long32   event_count;   /* nr of pending events */
 
370
   u_long32   exec_count;    /* nr of executed events */
 
371
}m_tet_t;
 
372
 
 
373
#define MONITOR_TET_COUNT(monitor)  if ((monitor->monitor_time > 0) && (monitor->ext_type == TET_EXT)) \
 
374
                                    ((m_tet_t*)(monitor->ext_data))->count++
 
375
 
 
376
#define MONITOR_TET_EVENT(monitor, inc)  if ((monitor->monitor_time > 0) && (monitor->ext_type == TET_EXT)) \
 
377
                                    ((m_tet_t*)(monitor->ext_data))->event_count += inc
 
378
 
 
379
#define MONITOR_TET_EXEC(monitor)  if ((monitor->monitor_time > 0) && (monitor->ext_type == TET_EXT)) \
 
380
                                    ((m_tet_t*)(monitor->ext_data))->exec_count++
 
381
 
 
382
 
 
383
#endif /* _SGE_MONITIR_H */