Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix the race condition in _xbt_log_cat_init().
[simgrid.git] / src / xbt / log.c
index f8c7a23..7ec8465 100644 (file)
 #include "xbt/sysdep.h"
 #include "xbt/log_private.h"
 #include "xbt/dynar.h"
+#include "xbt/xbt_os_thread.h"
 
 XBT_PUBLIC_DATA(int) (*xbt_pid) ();
 int xbt_log_no_loc = 0;         /* if set to true (with --log=no_loc), file localization will be omitted (for tesh tests) */
+static xbt_os_rmutex_t log_cat_init_mutex = NULL;
 
 /** \addtogroup XBT_log
  *
@@ -182,14 +184,10 @@ compile with the -Wall option, gcc will warn you for unmatched arguments, ie
 when you pass a pointer to a string where an integer was specified by the
 format. This is usually a good idea.
 
-Because some C compilers do not support vararg macros, there is a version of
-the macro for any number of arguments from 0 to 6. The macro name ends with
-the total number of arguments.
-
 Here is an example of the most basic type of macro. This is a logging
 request with priority <i>warning</i>.
 
-<code>CLOG5(MyCat, gras_log_priority_warning, "Values are: %d and '%s'", 5,
+<code>XBT_CLOG(MyCat, gras_log_priority_warning, "Values are: %d and '%s'", 5,
 "oops");</code>
 
 A logging request is said to be enabled if its priority is higher than or
@@ -202,7 +200,7 @@ example, one of the standard priorities is used, then there is a convenience
 macro that is typically used instead. For example, the above example is
 equivalent to the shorter:
 
-<code>CWARN4(MyCat, "Values are: %d and '%s'", 5, "oops");</code>
+<code>XBT_CWARN(MyCat, "Values are: %d and '%s'", 5, "oops");</code>
 
 \section log_API_isenabled 2.3 Checking if a particular category/priority is enabled
 
@@ -220,7 +218,7 @@ If \ref XBT_LOG_NEW_DEFAULT_SUBCATEGORY(MyCat, Parent) or
 \ref XBT_LOG_NEW_DEFAULT_CATEGORY(MyCat) is used to create the
 category, then the even shorter form can be used:
 
-<code>WARN3("Values are: %s and '%d'", 5, "oops");</code>
+<code>XBT_WARN("Values are: %s and '%d'", 5, "oops");</code>
 
 Only one default category can be created per file, though multiple
 non-defaults can be created and used.
@@ -230,28 +228,21 @@ non-defaults can be created and used.
 First of all, each module should register its own category into the categories
 tree using \ref XBT_LOG_NEW_DEFAULT_SUBCATEGORY.
 
-Then, logging should be done with the DEBUG<n>, VERB<n>, INFO<n>, WARN<n>,
-ERROR<n> or CRITICAL<n> macro families (such as #DEBUG10, #VERB10,
-#INFO10, #WARN10, #ERROR10 and #CRITICAL10). For each group, there is at
-least 11 different macros (like DEBUG0, DEBUG1, DEBUG2, DEBUG3, DEBUG4 and
-DEBUG5, DEBUG6, DEBUG7, DEBUG8, DEBUG9, DEBUG10), only differing in the number of arguments passed along the format.
-This is because we want SimGrid itself to keep compilable on ancient
-compiler not supporting variable number of arguments to macros. But we
-should provide a macro simpler to use for the users not interested in SP3
-machines (FIXME).
+Then, logging should be done with the #XBT_DEBUG, #XBT_VERB, #XBT_INFO,
+#XBT_WARN, #XBT_ERROR and #XBT_CRITICAL macros.
 
 Under GCC, these macro check there arguments the same way than printf does. So,
 if you compile with -Wall, the following code will issue a warning:
-<code>DEBUG2("Found %s (id %f)", some_string, a_double)</code>
+<code>XBT_DEBUG("Found %s (id %d)", some_string, a_double)</code>
 
 If you want to specify the category to log onto (for example because you
 have more than one category per file, add a C before the name of the log
-producing macro (ie, use #CDEBUG10, #CVERB10, #CINFO10, #CWARN10, #CERROR10 and
-#CCRITICAL10 and friends), and pass the category name as first argument.
+producing macro (ie, use #XBT_CDEBUG, #XBT_CVERB, #XBT_CINFO, #XBT_CWARN,
+#XBT_CERROR and #XBT_CCRITICAL and friends), and pass the category name as
+first argument.
 
 The TRACE priority is not used the same way than the other. You should use
-the #XBT_IN, XBT_IN<n> (up to #XBT_IN5), #XBT_OUT and #XBT_HERE macros
-instead.
+the #XBT_IN, #XBT_OUT and #XBT_HERE macros instead.
 
 \section log_API_example 2.6 Example of use
 
@@ -269,17 +260,17 @@ int main() {
        xbt_log_control_set("SA.thresh:3");
 
        / * This request is enabled, because WARNING >= INFO. * /
-       CWARN0(VSS, "Low fuel level.");
+       XBT_CWARN(VSS, "Low fuel level.");
 
        / * This request is disabled, because DEBUG < INFO. * /
-       CDEBUG0(VSS, "Starting search for nearest gas station.");
+       XBT_CDEBUG(VSS, "Starting search for nearest gas station.");
 
        / * The default category SA inherits its priority from VSS. Thus,
           the following request is enabled because INFO >= INFO.  * /
-       INFO0("Located nearest gas station.");
+       XBT_INFO("Located nearest gas station.");
 
        / * This request is disabled, because DEBUG < INFO. * /
-       DEBUG0("Exiting gas station search");
+       XBT_DEBUG("Exiting gas station search");
 }
 \endverbatim
 
@@ -309,7 +300,15 @@ displayed by setting a threshold to each category through the
 For example, \verbatim --log=root.thres:debug\endverbatim will make
 SimGrid <b>extremely</b> verbose while \verbatim
 --log=root.thres:critical\endverbatim should shut it almost
-completely off.
+completely off. The full list of recognized thresholds is the following:
+
+ - trace: enter and return of some functions
+ - debug: crufty output
+ - verbose: verbose output for the user wanting more
+ - info: output about the regular functionning
+ - warning: minor issue encountered
+ - error: issue encountered
+ - critical: major issue encountered 
 
 \subsection log_use_conf_multi 3.1.2 Passing several settings
 
@@ -372,10 +371,17 @@ library itself, or test programs doing strange things) do not display the
 process identity (thus, fmt is '[%%r] %%l: [%%c/%%p] %%m%%n' in that case, and '[%%r]
 [%%c/%%p] %%m%%n' if they are at priority INFO).
 
-For now, there is only one format modifier: the precision field. You
-can for example specify %.4r to get the application age with 4
-numbers after the radix. Another limitation is that you cannot set
-specific layouts to the several priorities.
+For now, there is only two format modifiers: the precision and the
+width fields. You can for example specify %.4r to get the application
+age with 4 numbers after the radix, or %15p to get the process name
+on 15 columns. Finally, you can specify %10.6r to get the time on at
+most 10 columns, with 6 numbers after the radix. 
+
+Note that when specifying the width, it is filled with spaces. That
+is to say that for example %5r in your format is converted to "% 5f"
+for printf (note the extra space); there is no way to fill the empty
+columns with 0 (ie, pass "%05f" to printf). Another limitation is
+that you cannot set specific layouts to the several priorities.
 
 \subsection log_use_conf_app 3.1.4 Category appender
 
@@ -460,11 +466,7 @@ The default appender function currently prints to stderr, and the only other
 existing one writes to the specified file. More would be needed, like the one
 able to send the logs to a remote dedicated server.
 This is on our TODO list for quite a while now, but your help would be
-welcome here, too.
-
-
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              *//*' */
-
+welcome here, too. */
 
 xbt_log_appender_t xbt_log_default_appender = NULL;     /* set in log_init */
 xbt_log_layout_t xbt_log_default_layout = NULL; /* set in log_init */
@@ -530,6 +532,7 @@ void xbt_log_preinit(void)
   xbt_log_default_layout = xbt_log_layout_simple_new(NULL);
   _XBT_LOGV(XBT_LOG_ROOT_CAT).appender = xbt_log_default_appender;
   _XBT_LOGV(XBT_LOG_ROOT_CAT).layout = xbt_log_default_layout;
+  log_cat_init_mutex = xbt_os_rmutex_init();
 }
 
 /** @brief Get all logging settings from the command line
@@ -553,14 +556,14 @@ void xbt_log_init(int *argc, char **argv)
         !strncmp(argv[i], "--xbt-log=", strlen("--xbt-log="))) {
 
       if (strncmp(argv[i], "--log=", strlen("--log=")))
-        WARN2
+        XBT_WARN
             ("Option %.*s is deprecated and will disapear in the future. Use --log instead.",
              (int) (strchr(argv[i], '=') - argv[i]), argv[i]);
 
       opt = strchr(argv[i], '=');
       opt++;
       xbt_log_control_set(opt);
-      DEBUG1("Did apply '%s' as log setting", opt);
+      XBT_DEBUG("Did apply '%s' as log setting", opt);
       /*remove this from argv */
 
       for (j = i + 1; j < *argc; j++) {
@@ -595,7 +598,8 @@ static void log_cat_exit(xbt_log_category_t cat)
 
 void xbt_log_postexit(void)
 {
-  VERB0("Exiting log");
+  XBT_VERB("Exiting log");
+  xbt_os_rmutex_destroy(log_cat_init_mutex);
   xbt_dynar_free(&xbt_log_settings);
   log_cat_exit(&_XBT_LOGV(XBT_LOG_ROOT_CAT));
 }
@@ -610,7 +614,7 @@ void _xbt_log_event_log(xbt_log_event_t ev, const char *fmt, ...)
   while (1) {
     xbt_log_appender_t appender = cat->appender;
     if (appender != NULL) {
-      xbt_assert1(cat->layout,
+      xbt_assert(cat->layout,
                   "No valid layout for the appender of category %s",
                   cat->name);
       cat->layout->do_layout(cat->layout, ev, fmt, appender);
@@ -648,7 +652,7 @@ static void _xbt_log_cat_apply_set(xbt_log_category_t category,
   if (setting->thresh != xbt_log_priority_uninitialized) {
     xbt_log_threshold_set(category, setting->thresh);
 
-    DEBUG3("Apply settings for category '%s': set threshold to %s (=%d)",
+    XBT_DEBUG("Apply settings for category '%s': set threshold to %s (=%d)",
            category->name, xbt_log_priority_names[category->threshold],
            category->threshold);
   }
@@ -656,14 +660,14 @@ static void _xbt_log_cat_apply_set(xbt_log_category_t category,
   if (setting->fmt) {
     xbt_log_layout_set(category, xbt_log_layout_format_new(setting->fmt));
 
-    DEBUG2("Apply settings for category '%s': set format to %s",
+    XBT_DEBUG("Apply settings for category '%s': set format to %s",
            category->name, setting->fmt);
   }
 
   if (setting->additivity != -1) {
     xbt_log_additivity_set(category, setting->additivity);
 
-    DEBUG2("Apply settings for category '%s': set additivity to %s",
+    XBT_DEBUG("Apply settings for category '%s': set additivity to %s",
            category->name, (setting->additivity ? "on" : "off"));
   }
   if (setting->appender) {
@@ -671,7 +675,7 @@ static void _xbt_log_cat_apply_set(xbt_log_category_t category,
     if (!category->layout)
       xbt_log_layout_set(category, xbt_log_layout_simple_new(NULL));
     category->additivity = 0;
-    DEBUG2("Set %p as appender of category '%s'",
+    XBT_DEBUG("Set %p as appender of category '%s'",
            setting->appender, category->name);
   }
 #undef _xbt_log_cat_init
@@ -687,11 +691,17 @@ int _xbt_log_cat_init(xbt_log_category_t category,
 {
 #define _xbt_log_cat_init(a, b) (0)
 
+  xbt_os_rmutex_acquire(log_cat_init_mutex);
+  if (category->threshold != xbt_log_priority_uninitialized) {
+    xbt_os_rmutex_release(log_cat_init_mutex);
+    return priority >= category->threshold;
+  }
+
   unsigned int cursor;
   xbt_log_setting_t setting = NULL;
   int found = 0;
 
-  DEBUG3("Initializing category '%s' (firstChild=%s, nextSibling=%s)",
+  XBT_DEBUG("Initializing category '%s' (firstChild=%s, nextSibling=%s)",
          category->name,
          (category->firstChild ? category->firstChild->name : "none"),
          (category->nextSibling ? category->nextSibling->name : "none"));
@@ -706,7 +716,7 @@ int _xbt_log_cat_init(xbt_log_category_t category,
     if (!category->parent)
       category->parent = &_XBT_LOGV(XBT_LOG_ROOT_CAT);
 
-    DEBUG3("Set %s (%s) as father of %s ",
+    XBT_DEBUG("Set %s (%s) as father of %s ",
            category->parent->name,
            (category->parent->threshold == xbt_log_priority_uninitialized ?
             "uninited" : xbt_log_priority_names[category->
@@ -728,7 +738,7 @@ int _xbt_log_cat_init(xbt_log_category_t category,
         cpp = cpp->nextSibling;
       }
 
-      DEBUG3("Childs of %s: %s; nextSibling: %s",
+      XBT_DEBUG("Childs of %s: %s; nextSibling: %s",
              category->parent->name, res,
              (category->parent->nextSibling ?
               category->parent->nextSibling->name : "none"));
@@ -739,15 +749,17 @@ int _xbt_log_cat_init(xbt_log_category_t category,
   }
 
   /* Apply the control */
-  if (!xbt_log_settings)
+  if (!xbt_log_settings) {
+    xbt_os_rmutex_release(log_cat_init_mutex);
     return priority >= category->threshold;
+  }
 
-  xbt_assert0(category, "NULL category");
+  xbt_assert(category, "NULL category");
   xbt_assert(category->name);
 
   xbt_dynar_foreach(xbt_log_settings, cursor, setting) {
-    xbt_assert0(setting, "Damnit, NULL cat in the list");
-    xbt_assert1(setting->catname, "NULL setting(=%p)->catname",
+    xbt_assert(setting, "Damnit, NULL cat in the list");
+    xbt_assert(setting->catname, "NULL setting(=%p)->catname",
                 (void *) setting);
 
     if (!strcmp(setting->catname, category->name)) {
@@ -761,10 +773,11 @@ int _xbt_log_cat_init(xbt_log_category_t category,
   }
 
   if (!found)
-    DEBUG3("Category '%s': inherited threshold = %s (=%d)",
+    XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)",
            category->name, xbt_log_priority_names[category->threshold],
            category->threshold);
 
+  xbt_os_rmutex_release(log_cat_init_mutex);
   return priority >= category->threshold;
 
 #undef _xbt_log_cat_init
@@ -772,9 +785,8 @@ int _xbt_log_cat_init(xbt_log_category_t category,
 
 void xbt_log_parent_set(xbt_log_category_t cat, xbt_log_category_t parent)
 {
-
-  xbt_assert0(cat, "NULL category to be given a parent");
-  xbt_assert1(parent, "The parent category of %s is NULL", cat->name);
+  xbt_assert(cat, "NULL category to be given a parent");
+  xbt_assert(parent, "The parent category of %s is NULL", cat->name);
 
   /*
    * if the threshold is initialized
@@ -806,7 +818,6 @@ void xbt_log_parent_set(xbt_log_category_t cat, xbt_log_category_t parent)
   cat->threshold = parent->threshold;
 
   cat->isThreshInherited = 1;
-
 }
 
 static void _set_inherited_thresholds(xbt_log_category_t cat)
@@ -817,7 +828,7 @@ static void _set_inherited_thresholds(xbt_log_category_t cat)
   for (; child != NULL; child = child->nextSibling) {
     if (child->isThreshInherited) {
       if (cat != &_XBT_LOGV(log))
-        VERB3("Set category threshold of %s to %s (=%d)",
+        XBT_VERB("Set category threshold of %s to %s (=%d)",
               child->name, xbt_log_priority_names[cat->threshold],
               cat->threshold);
       child->threshold = cat->threshold;
@@ -852,7 +863,7 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
 
   if (!*control_string)
     return set;
-  DEBUG1("Parse log setting '%s'", control_string);
+  XBT_DEBUG("Parse log setting '%s'", control_string);
 
   control_string += strspn(control_string, " ");
   name = control_string;
@@ -862,7 +873,7 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
   eq = control_string;
   control_string += strcspn(control_string, " ");
 
-  xbt_assert1(*dot == '.' && (*eq == '=' || *eq == ':'),
+  xbt_assert(*dot == '.' && (*eq == '=' || *eq == ':'),
               "Invalid control string '%s'", control_string);
 
   if (!strncmp(dot + 1, "thresh", (size_t) (eq - dot - 1))) {
@@ -876,17 +887,17 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
       }
     }
 
-    DEBUG1("New priority name = %s", neweq);
+    XBT_DEBUG("New priority name = %s", neweq);
     for (i = 0; i < xbt_log_priority_infinite; i++) {
       if (!strncmp(xbt_log_priority_names[i], neweq, p - eq)) {
-        DEBUG1("This is priority %d", i);
+        XBT_DEBUG("This is priority %d", i);
         break;
       }
     }
     if (i < xbt_log_priority_infinite) {
       set->thresh = (e_xbt_log_priority_t) i;
     } else {
-      THROW1(arg_error, 0,
+      THROWF(arg_error, 0,
              "Unknown priority name: %s (must be one of: trace,debug,verbose,info,warning,error,critical)",
              eq + 1);
     }
@@ -917,7 +928,7 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
     if (!strncmp(neweq, "file:", 5)) {
       set->appender = xbt_log_appender_file_new(neweq + 5);
     } else {
-      THROW1(arg_error, 0, "Unknown appender log type: '%s'", neweq);
+      THROWF(arg_error, 0, "Unknown appender log type: '%s'", neweq);
     }
     free(neweq);
   } else if (!strncmp(dot + 1, "fmt", (size_t) (eq - dot - 1))) {
@@ -925,14 +936,14 @@ static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
   } else {
     char buff[512];
     snprintf(buff, min(512, eq - dot), "%s", dot + 1);
-    THROW1(arg_error, 0, "Unknown setting of the log category: '%s'",
+    THROWF(arg_error, 0, "Unknown setting of the log category: '%s'",
            buff);
   }
   set->catname = (char *) xbt_malloc(dot - name + 1);
 
   memcpy(set->catname, name, dot - name);
   set->catname[dot - name] = '\0';      /* Just in case */
-  DEBUG1("This is for cat '%s'", set->catname);
+  XBT_DEBUG("This is for cat '%s'", set->catname);
 
   return set;
 }
@@ -942,14 +953,14 @@ static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat,
 {
   xbt_log_category_t child, res;
 
-  DEBUG4("Search '%s' into '%s' (firstChild='%s'; nextSibling='%s')", name,
+  XBT_DEBUG("Search '%s' into '%s' (firstChild='%s'; nextSibling='%s')", name,
          cat->name, (cat->firstChild ? cat->firstChild->name : "none"),
          (cat->nextSibling ? cat->nextSibling->name : "none"));
   if (!strcmp(cat->name, name))
     return cat;
 
   for (child = cat->firstChild; child != NULL; child = child->nextSibling) {
-    DEBUG1("Dig into %s", child->name);
+    XBT_DEBUG("Dig into %s", child->name);
     res = _xbt_log_cat_searchsub(child, name);
     if (res)
       return res;
@@ -992,7 +1003,7 @@ void xbt_log_control_set(const char *control_string)
 
   if (!control_string)
     return;
-  DEBUG1("Parse log settings '%s'", control_string);
+  XBT_DEBUG("Parse log settings '%s'", control_string);
 
   /* Special handling of no_loc request, which asks for any file localization to be omitted (for tesh runs) */
   if (!strcmp(control_string, "no_loc")) {
@@ -1022,13 +1033,13 @@ void xbt_log_control_set(const char *control_string)
         _xbt_log_cat_searchsub(&_XBT_LOGV(XBT_LOG_ROOT_CAT), set->catname);
 
     if (cat) {
-      DEBUG0("Apply directly");
+      XBT_DEBUG("Apply directly");
       _xbt_log_cat_apply_set(cat, set);
       _free_setting((void *) &set);
     } else {
 
-      DEBUG0("Store for further application");
-      DEBUG1("push %p to the settings", (void *) set);
+      XBT_DEBUG("Store for further application");
+      XBT_DEBUG("push %p to the settings", (void *) set);
       xbt_dynar_push(xbt_log_settings, &set);
     }
   }
@@ -1047,22 +1058,22 @@ void xbt_log_appender_set(xbt_log_category_t cat, xbt_log_appender_t app)
 
 void xbt_log_layout_set(xbt_log_category_t cat, xbt_log_layout_t lay)
 {
+#define _xbt_log_cat_init(a, b) (0)
   if (!cat->appender) {
-    VERB1
+    XBT_VERB
         ("No appender to category %s. Setting the file appender as default",
          cat->name);
     xbt_log_appender_set(cat, xbt_log_appender_file_new(NULL));
   }
-  if (cat->layout && cat != &_XBT_LOGV(root)) {
-    /* better leak the default layout than check every categories to
-       change it */
+  if (cat->layout) {
     if (cat->layout->free_) {
       cat->layout->free_(cat->layout);
-      free(cat->layout);
     }
+    free(cat->layout);
   }
   cat->layout = lay;
   xbt_log_additivity_set(cat, 0);
+#undef _xbt_log_cat_init
 }
 
 void xbt_log_additivity_set(xbt_log_category_t cat, int additivity)