1
1
openmpi/orte/mca/notifier/notifier_event_calls.h

171 строка
5.8 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2009 Bull SAS. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef ORTE_NOTIFIER_EVENTS_CALLS_H
#define ORTE_NOTIFIER_EVENTS_CALLS_H
#include "orte_config.h"
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif /* HAVE_STDIO_H */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAVE_SYS_TIME_H */
#include "opal/class/opal_object.h"
BEGIN_C_DECLS
#define ORTE_NOTIFIER_LOG_0 0 /* Initial log format needed (no delay) */
#define ORTE_NOTIFIER_LOG_1 1 /* Intermediate log format needed (delay) */
#define ORTE_NOTIFIER_LOG_2 2 /* Final log format needed (at finalize) */
ORTE_DECLSPEC bool notifier_log_event_enabled(void);
ORTE_DECLSPEC void notifier_event_store(orte_notifier_event_t *);
ORTE_DECLSPEC void notifier_trace_event(int, int, int32_t, time_t, time_t,
const char *);
/*
* Do not use this function directly: use ORTE_NOTIFIER_DEFINE_EVENT() instead
*/
static inline orte_notifier_event_t *notifier_alloc_event(int ev_id,
const char *msg)
{
orte_notifier_event_t *ev;
ev = OBJ_NEW(orte_notifier_event_t);
if (NULL == ev) {
return NULL;
}
asprintf(&ev->ev_msg, msg);
if (NULL == ev->ev_msg) {
OBJ_RELEASE(ev);
return NULL;
}
ev->ev_id = ev_id;
/*
* Store the allocated event into a list to be able to manage the
* unconditional event tracing and freeing during finalize.
*/
notifier_event_store(ev);
return ev;
}
static inline void notifier_count_and_log_event(orte_notifier_event_t *ev,
int ev_id,
int cnt_thresh,
int time_thresh)
{
time_t now, delay;
int32_t count;
opal_atomic_add_32(&ev->ev_cnt, 1);
if (ev->ev_cnt <= cnt_thresh) {
return;
}
count = ev->ev_cnt;
now = time(NULL);
if (ev->ev_already_traced) {
if (now > ev->ev_time_trc + time_thresh) {
delay = now - ev->ev_time_trc;
ev->ev_cnt = 0;
ev->ev_time_trc = now;
notifier_trace_event(ORTE_NOTIFIER_LOG_1, ev_id, count, now, delay,
ev->ev_msg);
}
} else {
ev->ev_already_traced = 1;
ev->ev_cnt = 0;
ev->ev_time_trc = now;
/* We don't care about the delay for the very 1st trace */
notifier_trace_event(ORTE_NOTIFIER_LOG_0, ev_id, count, now, now,
ev->ev_msg);
}
}
#define notifier_event_fn_prefix(i) notifier_log_event_ ## i
/*
* This macro should be called each time a new event will be traced.
* It expands to a static inline function suffixed by the event number.
*/
#define ORTE_NOTIFIER_DEFINE_EVENT(i, m) \
static inline void notifier_event_fn_prefix(i) (int c_thr, int t_thr) \
{ \
static orte_notifier_event_t *prefix_ ## i = NULL; \
if (!notifier_log_event_enabled()) { \
return; \
} \
if (NULL == prefix_ ## i) { \
prefix_ ## i = notifier_alloc_event(i, m); \
if (NULL == prefix_ ## i) { \
return; \
} \
} \
notifier_count_and_log_event(prefix_ ## i, i, c_thr, t_thr); \
}
/*
* This is the log interface that should be called whenever an unsual event
* should be warned about.
* The event should have been defined before, using
* ORTE_NOTIFIER_DEFINE_EVENT():
*
* (1) Event definition:
*
* Typically in a header file call the following:
* ORTE_NOTIFIER_DEFINE_EVENT(0, "message 0")
* This macro expands to
* static inline void notifier_log_event_0(int c_thr, int t_thr)
* {
* static orte_notifier_event_t *prefix_0 = NULL;
* if (!notifier_log_event_enabled()) {
* return;
* }
* if (NULL == prefix_0) {
* prefix_0 = notifier_alloc_event(0, "message 0");
* if (NULL == prefix_0) {
* return;
* }
* }
* notifier_count_and_log_event(prefix_0, 0, c_thr, t_thr);
* }
*
* (2) Event accounting and tracing:
*
* Whenever you want to trace the unusual event whose id is 0, just call:
* ORTE_NOTIFIER_LOG_EVENT(0, 100, 1);
* 100 and 1 are respectively the counter and time thresholds.
* This actually expands to
* notifier_log_event_0(100, 1);
*/
#define ORTE_NOTIFIER_LOG_EVENT(i, c, t) notifier_event_fn_prefix(i) (c, t)
END_C_DECLS
#endif /* ORTE_NOTIFIER_EVENT_CALLS_H */