Skip to content

Commit

Permalink
Merge SVN 5254
Browse files Browse the repository at this point in the history
  • Loading branch information
ddeclerck committed Feb 16, 2025
1 parent 710229b commit 611e5eb
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 44 deletions.
6 changes: 3 additions & 3 deletions libcob/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@
2024-03-17 Fabrice Le Fessant <[email protected]>
Emilien Lemaire <[email protected]>

* Makefile.am: add `profiling.c` to sources
* profiling.c: implement profiling functions
(time spent in each procedure of the program)
* common.c: add 4 environments variables COB_PROF_FILE,
COB_PROF_MAX_DEPTH,COB_PROF_ENABLE and COB_PROF_FORMAT
* Makefile.am: add profiling.c to sources
* common.c: add runtime settings COB_PROF_FILE, COB_PROF_MAX_DEPTH,
COB_PROF_ENABLE and COB_PROF_FORMAT
* common.c (cob_expand_env_string): add $b (executable basename),
$f (executable filename), $d (date in yyyymmdd) and
$t (time in hhmmss)
Expand Down
28 changes: 14 additions & 14 deletions libcob/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -3124,44 +3124,44 @@ enum cob_prof_procedure_kind {

struct cob_prof_procedure {
/* Name of the module or section or paragraph or entry */
const char *text;
const char *text;
/* File Location */
const char *file;
int line;
const char *file;
int line;
/* Index of the section record of this procedure. In the case
of COB_PROF_PROCEDURE_ENTRY, the "section" field is in fact
the paragraph, not the section */
int section;
int section;
/* Kind of procedure. */
enum cob_prof_procedure_kind kind;
enum cob_prof_procedure_kind kind;
};

/* Structure storing profiling information about each COBOL module */
struct cob_prof_module {
/* Array of execution times */
cob_ns_time *total_times;
cob_ns_time *total_times;
/* Array of execution counts */
unsigned int *called_count;
unsigned int *called_count;
/* Array of current recursions per procedure */
unsigned int *procedure_recursions;
unsigned int *procedure_recursions;
/* Array of procedure descriptions */
struct cob_prof_procedure *procedures ;
struct cob_prof_procedure *procedures ;
/* Number of procedures */
size_t procedure_count;
size_t procedure_count;
};

/* Function called to start profiling a COBOL module. Allocates the
cob_prof_module structure that will be used to store the counters and
times. */
COB_EXPIMP struct cob_prof_module *cob_prof_init_module (
cob_module *module,
struct cob_prof_procedure *procedure_names,
size_t procedure_count);
struct cob_prof_procedure *procedure_names,
size_t procedure_count);

/* Functions used to instrument the generated C code and measure
* counters and times */
COB_EXPIMP void cob_prof_enter_procedure (struct cob_prof_module *, int);
COB_EXPIMP void cob_prof_exit_procedure (struct cob_prof_module *, int);
COB_EXPIMP void cob_prof_enter_procedure (struct cob_prof_module *, int);
COB_EXPIMP void cob_prof_exit_procedure (struct cob_prof_module *, int);
COB_EXPIMP void cob_prof_enter_section (struct cob_prof_module *, int);
COB_EXPIMP void cob_prof_exit_section (struct cob_prof_module *, int);

Expand Down
6 changes: 4 additions & 2 deletions libcob/fbdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,14 @@ bdb_close_index (cob_file *f, int index)

static int
bdb_bt_compare (DB *db, const DBT *k1, const DBT *k2
#if DB_VERSION_MAJOR >= 6 /* ABI break in DB_VERSION_FAMILY 6 ... */
#if DB_VERSION_MAJOR >= 6 /* ABI break in DB_VERSION_FAMILY 12 ... */
, size_t *locp
#endif
)
{
const unsigned char *col = (unsigned char *)DBT_GET_APP_DATA(k1);
const unsigned char *col = (unsigned char *)DBT_GET_APP_DATA (k1);
COB_UNUSED (db);

/* LCOV_EXCL_START */
if (col == NULL) {
cob_runtime_error ("bdb_bt_compare was set but no collating sequence was stored in DBT");
Expand Down
10 changes: 6 additions & 4 deletions libcob/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -5277,14 +5277,16 @@ lineseq_read (cob_file_api *a, cob_file *f, const int read_opts)
&& (f->file_features & COB_FILE_LS_SPLIT)) {
/* If record is too long, then simulate end
* so balance becomes the next record read */
off_t k = 1;
long k;
n = getc (fp);
if (n == '\r') {
n = getc (fp);
k++;
k = -2;
} else {
k = -1;
}
if (n != '\n') {
fseek (fp, -k, SEEK_CUR);
fseek (fp, k, SEEK_CUR);
if (!(COB_MODULE_PTR
&& COB_MODULE_PTR->flag_dialect == COB_DIALECT_MF))
sts = COB_STATUS_06_READ_TRUNCATE;
Expand Down Expand Up @@ -8489,7 +8491,7 @@ cob_sys_copy_file (unsigned char *fname1, unsigned char *fname2)
flag |= O_CREAT | O_TRUNC | O_WRONLY;
fd2 = open (file_open_name, flag, COB_FILE_MODE);
if (fd2 == -1) {
int ret = errno_cob_sts (COB_STATUS_35_NOT_EXISTS);
ret = errno_cob_sts (COB_STATUS_35_NOT_EXISTS);
close (fd1);
return ret;
}
Expand Down
45 changes: 24 additions & 21 deletions libcob/profiling.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
Copyright (C) 2023-2024 Free Software Foundation, Inc.
Written by Emilien Lemaire and Fabrice Le Fessant.
Written by Emilien Lemaire, Fabrice Le Fessant, David Declerck,
Simon Sobisch.
This file is part of GnuCOBOL.
Expand Down Expand Up @@ -38,7 +39,7 @@
#include <unistd.h>
#endif

#ifdef _WIN32
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
Expand All @@ -54,29 +55,29 @@ static struct cob_prof_module_list *prof_info_list ;

/* We maintain a stack of the procedures entered as 3 different
* arrays, with "current_idx" being the stack pointer. */
static cob_ns_time *start_times;
static int *called_procedures;
static struct cob_prof_module* *called_runtimes;
static cob_ns_time *start_times;
static int *called_procedures;
static struct cob_prof_module **called_runtimes;
/* Current size of previous arrays */
static int max_prof_depth;
static int current_idx = -1;

/* Whether profiling is active or not. */
static int is_active = 0;
static int is_active = -1;

/* Which clock to use for clock_gettime (if available) */
#ifdef HAVE_CLOCK_GETTIME
static clockid_t clockid = CLOCK_REALTIME;
static clockid_t clockid = CLOCK_REALTIME;
#endif

/* Cached clock frequency on Windows */
#ifdef _WIN32
static LONGLONG qpc_freq = 0;
static LONGLONG qpc_freq = 0;
#endif

/* Remember static and dynamic configuration */
static cob_global *cobglobptr = NULL;
static cob_settings *cobsetptr = NULL;
static cob_global *cobglobptr = NULL;
static cob_settings *cobsetptr = NULL;



Expand Down Expand Up @@ -148,28 +149,27 @@ prof_setup_clock ()
static void
prof_init_static ()
{
static int init_done = 0;

if (!init_done && cobsetptr) {
if (is_active == -1 && cobsetptr) {
prof_setup_clock ();
is_active = cobsetptr->cob_prof_enable;
init_done = 1;
}
}

void
cob_init_prof (cob_global *lptr, cob_settings *sptr)
{
cobglobptr = lptr;
cobsetptr = sptr;
cobsetptr = sptr;
}

struct cob_prof_module *
cob_prof_init_module (cob_module *module,
struct cob_prof_procedure *procedures,
size_t procedure_count)
{
prof_init_static();
COB_UNUSED (module);

prof_init_static ();
if (is_active){
struct cob_prof_module *info;
struct cob_prof_module_list *item;
Expand Down Expand Up @@ -200,7 +200,8 @@ cob_prof_realloc_arrays (void)

if (max_prof_depth >= new_size){
int i;
cob_runtime_warning (_("[cob_prof] Profiling overflow at %d calls, aborting profiling."), current_idx);
cob_runtime_warning (_("[cob_prof] Profiling overflow at %d calls, aborting profiling."),
current_idx);
cob_runtime_warning (_(" Last 10 calls on stack:"));
for (i = 0; i < cob_min_int(10, current_idx); i++){
struct cob_prof_module *info = called_runtimes[current_idx-1-i];
Expand Down Expand Up @@ -307,6 +308,8 @@ void
cob_prof_exit_section (struct cob_prof_module *info, int proc_idx)
{
/* For now, nothing to do */
COB_UNUSED (info);
COB_UNUSED (proc_idx);
}

void
Expand All @@ -330,13 +333,13 @@ print_monotonic_time (FILE *file, cob_ns_time t) {

cob_ns_time nanoseconds = t ;
cob_ns_time milliseconds = nanoseconds / 1000000;
unsigned int seconds = milliseconds / 1000;
milliseconds = milliseconds - 1000 * seconds;
unsigned int seconds = (unsigned int)(milliseconds / 1000);

if (seconds > 1000) {
fprintf (file, "%d s", seconds);
fprintf (file, "%u s", seconds);
} else {
fprintf (file, "%d.%03Ld s", seconds, milliseconds);
milliseconds = milliseconds - 1000 * seconds;
fprintf (file, "%u.%03u s", seconds, (unsigned int)milliseconds);
}
}

Expand Down

0 comments on commit 611e5eb

Please sign in to comment.