mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-13 12:53:53 +00:00
Branches: main, 11.07 A step towards getting a subset of deep profiling to work on Windows. runtime/mercury_conf_param.h: Re-order some definitions so that macros that specify C compiler or OS specific properties are defined first. This allows them to be used in subsequent definitions. Undefine MR_DEEP_PROFILING_TIMING if we are on Windows. Time profiling is not currently supported on Windows since it is implemented using setitimer and that function doesn't exist on Windows. (It does exist in Cygwin, but is rather dodgy IIRC -- I'll check on this separately a re-enable it in the Cygwin version if it turns out to work.) runtime/mercury_prof_time.[ch]: Fix incorrect guards: the contents of these files should only be visible if MR_DEEP_PROFILING_TIMING is enabled.
148 lines
3.6 KiB
C
148 lines
3.6 KiB
C
/*
|
|
** vim: ts=4 sw=4 expandtab
|
|
*/
|
|
/*
|
|
** Copyright (C) 2001-2002, 2005-2006 The University of Melbourne.
|
|
** This file may only be copied under the terms of the GNU Library General
|
|
** Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
*/
|
|
|
|
/*
|
|
** mercury_prof_time.c
|
|
**
|
|
** Author: petdr
|
|
*/
|
|
|
|
const char *MR_time_method;
|
|
|
|
#include "mercury_imp.h"
|
|
#include "mercury_signal.h"
|
|
#include "mercury_timing.h"
|
|
#include "mercury_prof_time.h"
|
|
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
|
|
#ifdef MR_HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#ifdef MR_HAVE_SYS_TIME_H
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#if defined(MR_MPROF_PROFILE_TIME) || defined(MR_DEEP_PROFILING_TIMING)
|
|
|
|
#if !defined(MR_CLOCK_TICKS_PER_SECOND) || !defined(MR_HAVE_SETITIMER)
|
|
#error "Time profiling not supported on this system"
|
|
#endif
|
|
|
|
static int MR_itimer_sig;
|
|
static int MR_itimer_type;
|
|
|
|
static MR_bool MR_time_profiling_on = MR_FALSE;
|
|
|
|
static void MR_checked_setitimer(int which, struct itimerval *value);
|
|
|
|
/*
|
|
** MR_init_time_profile_method:
|
|
**
|
|
** Initializes MR_itimer_type and MR_itimer_sig based on the setting of
|
|
** MR_time_profile_method.
|
|
*/
|
|
|
|
void
|
|
MR_init_time_profile_method(void)
|
|
{
|
|
switch (MR_time_profile_method) {
|
|
#if defined(ITIMER_REAL) && defined(SIGALRM)
|
|
case MR_profile_real_time:
|
|
MR_itimer_type = ITIMER_REAL;
|
|
MR_itimer_sig = SIGALRM;
|
|
MR_time_method = "real-time";
|
|
break;
|
|
#endif
|
|
#if defined(ITIMER_VIRTUAL) && defined(SIGVTALRM)
|
|
case MR_profile_user_time:
|
|
MR_itimer_type = ITIMER_VIRTUAL;
|
|
MR_itimer_sig = SIGVTALRM;
|
|
MR_time_method = "user-time";
|
|
break;
|
|
#endif
|
|
#if defined(ITIMER_PROF) && defined(SIGPROF)
|
|
case MR_profile_user_plus_system_time:
|
|
MR_itimer_type = ITIMER_PROF;
|
|
MR_itimer_sig = SIGPROF;
|
|
MR_time_method = "user-plus-system-time";
|
|
break;
|
|
#endif
|
|
default:
|
|
MR_fatal_error("invalid time profile method");
|
|
}
|
|
}
|
|
|
|
/*
|
|
** MR_turn_on_time_profiling:
|
|
**
|
|
** Sets up the profiling timer and starts it up. At the moment it is after
|
|
** every MR_CLOCK_TICKS_PER_PROF_SIG ticks of the clock.
|
|
**
|
|
** WARNING: SYSTEM SPECIFIC CODE. This code is not very portable, because
|
|
** it uses setitimer(), which is not part of POSIX.1 or ANSI C.
|
|
*/
|
|
|
|
void
|
|
MR_turn_on_time_profiling(MR_time_signal_handler handler)
|
|
{
|
|
struct itimerval itime;
|
|
const long prof_sig_interval_in_usecs =
|
|
MR_CLOCK_TICKS_PER_PROF_SIG *
|
|
(MR_USEC_PER_SEC / MR_CLOCK_TICKS_PER_SECOND);
|
|
|
|
MR_time_profiling_on = MR_TRUE;
|
|
|
|
itime.it_value.tv_sec = 0;
|
|
itime.it_value.tv_usec = prof_sig_interval_in_usecs;
|
|
itime.it_interval.tv_sec = 0;
|
|
itime.it_interval.tv_usec = prof_sig_interval_in_usecs;
|
|
|
|
MR_setup_signal(MR_itimer_sig, handler, MR_FALSE,
|
|
"cannot install signal handler");
|
|
MR_checked_setitimer(MR_itimer_type, &itime);
|
|
}
|
|
|
|
/*
|
|
** MR_turn_off_time_profiling:
|
|
**
|
|
** Turns off the time profiling.
|
|
*/
|
|
|
|
void
|
|
MR_turn_off_time_profiling(void)
|
|
{
|
|
struct itimerval itime;
|
|
|
|
if (! MR_time_profiling_on) {
|
|
return;
|
|
}
|
|
|
|
itime.it_value.tv_sec = 0;
|
|
itime.it_value.tv_usec = 0;
|
|
itime.it_interval.tv_sec = 0;
|
|
itime.it_interval.tv_usec = 0;
|
|
|
|
MR_checked_setitimer(MR_itimer_type, &itime);
|
|
}
|
|
|
|
static void
|
|
MR_checked_setitimer(int which, struct itimerval *value)
|
|
{
|
|
errno = 0;
|
|
if (setitimer(which, value, NULL) != 0) {
|
|
perror("Mercury runtime: cannot set timer for profiling");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
#endif /* MR_MPROF_PROFILE_TIME || MR_DEEP_PROFILING_TIMING */
|