bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Would timevar be accepted in gnulib?


From: Bruno Haible
Subject: Re: Would timevar be accepted in gnulib?
Date: Sun, 23 Sep 2018 11:42:04 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-134-generic; KDE/5.18.0; x86_64; ; )

Hi Akim,

> > 1) Simplify. I don't see the point of the DEFTIMEVAR layer with the enum.
> >   Couldn't the code just do
> >     timevar_t tv_total;
> >     timevar_t tv_reader;
> >     ..
> >   and
> >     init_timevar ();
> >     timevar_start (&tv_total);
> > 
> >     timevar_push (&tv_reader);
> >     reader ();
> >     timevar_pop (&tv_reader);
> 
> I’m not sure I understand what you mean here.  The timers are
> used in many places in the code, not just main().  We need some
> global definition somewhere, and we want to iterate over them
> when displaying the result.

OK, you have now stated the requirement. From an abstract point of view,
you have a list of globally defined objects, where "list" means a data
structure suitable for iteration. The IDs are only implementation artifacts
for the current implementation.

I can imagine four ways to implement such a list:

a) Through a separate file, which gets included at different places in the
   code.
     DEFTIMEVAR (TV_TOTAL                 , "total time")
     DEFTIMEVAR (TV_READER                , "reader")
     ...

b) Through a set of global variables and a globally allocated array:
     timevar_t tv_total = { "total time" };
     timevar_t tv_reader = { "reader" };
     ...
     timevar_t* all_timevars[] =
       {
         &tv_total,
         &tv_reader,
         ...
       };

c) Through a globally allocated array and a couple of convenience macros:
     timevar_t all_timevars[] =
       {
         { "total time" },
         #define tv_total &all_timevars[0]
         { "reader" },
         #define tv_reader &all_timevars[1]
         ...
       };

d) Through a set of global variables and a list constructed at run time:
     timevar_t tv_total = { "total time" };
     timevar_t tv_reader = { "reader" };
     ...
     gl_list_t all_timevars;
     void init_timevars (void)
     {
       ...
       all_timevars = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, 
true);
       gl_list_add_last (all_timevars, &tv_total);
       gl_list_add_last (all_timevars, &tv_reader);
       ...
     }

What I mean is that each approach has different benefits.

Approach (a) has the benefit that adding a new timevar is easy: just one
modification in a single place. The drawback is that
  - you need one extra source code file,
  - the developer needs to understand the abstraction (the fact that it's
    an iterable list of globally defined objects was not explicitly stated),
  - you need the artificial concept of the ID,
  - not much flexibility (e.g. you cannot process the list in reverse order,
    you cannot define a tree or list-of-lists instead of a list).

Approaches (b), (c), (d) have the advantage that the abstraction is easier
to understand, because it follows common C idioms (define structs and reference
them through pointers instead of IDs). And they add flexibility: If someone
wants a list-of-lists instead of a single list, it's obvious how to do the
change.
The drawbacks are:
(b): To add a new timevar, two places in the code need to be touched.
(c): none
(d): To add a new timevar, two places in the code need to be touched.

Note that (c), like (a), has the benefit that adding a new timevar is a
modification in a single place.

(d) has the further big advantage that the list can be configured at run time.
For example, if a compiler has dynamically loadable passes (like GNU ld), this
is essential.


What do you think? Do you think the list-of-lists use-case makes sense?
Do you think configuring the list at run time is something people may want
to do?

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]