Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use library init/fini functions for xbt initialization
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 6 May 2010 23:41:44 +0000 (23:41 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 6 May 2010 23:41:44 +0000 (23:41 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7707 48e7efb5-ca39-0410-a469-dd3cf9ba447f

14 files changed:
ChangeLog
include/xbt/log.h
include/xbt/misc.h
src/msg/global.c
src/xbt/backtrace_dummy.c
src/xbt/backtrace_linux.c
src/xbt/backtrace_windows.c
src/xbt/dict.c
src/xbt/fifo.c
src/xbt/log.c
src/xbt/xbt_main.c
src/xbt/xbt_os_thread.c
src/xbt/xbt_sg_stubs.c
src/xbt_modinter.h

index 7fb0258..0e8f1ef 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@ SimGrid (3.5) unstable; urgency=low
  * New function: xbt_dict_cursor_set_data()
  * New function: xbt_fifo_get_last_item()
  * Bug fix in xbt_dynar_shrink(): use the right element size
+ * Use library init/fini functions for our initialization.
+   - you can use logs and other feature as soon as you want in your
+     code (even before the xbt_init / MSG_init)
+   - xbt_exit is now a no-op.
 
  -- Da SimGrid team <simgrid-devel@lists.gforge.inria.fr> 
 
index d22e627..1502558 100644 (file)
@@ -92,7 +92,7 @@ SG_BEGIN_DECL()
 /* The root of the category hierarchy. */
 #define XBT_LOG_ROOT_CAT   root
 
-/* In stric ansi C, we are not allowed to initialize a variable with 
+/* In strict ansi C, we are not allowed to initialize a variable with
  * a non-constant value. But the whole tree of categories is
  * connected by setting the address of the parent category as a field
  * of the child one.
index 3b89b3e..5ee2661 100644 (file)
@@ -10,7 +10,7 @@
 #define XBT_MISC_H
 
 /* Attributes are only in recent versions of GCC */
-#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))
 # define _XBT_GNUC_PRINTF( format_idx, arg_idx )    \
           __attribute__((__format__ (__printf__, format_idx, arg_idx)))
 # define _XBT_GNUC_SCANF( format_idx, arg_idx )     \
@@ -19,6 +19,9 @@
                   __attribute__((__format_arg__ (arg_idx)))
 # define _XBT_GNUC_NORETURN __attribute__((__noreturn__))
 # define _XBT_GNUC_UNUSED  __attribute__((unused))
+# define _XBT_GNUC_CONSTRUCTOR __attribute__((__constructor__))
+# define _XBT_GNUC_DESTRUCTOR __attribute__((__destructor__))
+# undef _XBT_NEED_INIT_PRAGMA
 
 #else /* !__GNUC__ */
 # define _XBT_GNUC_PRINTF( format_idx, arg_idx )
@@ -26,6 +29,9 @@
 # define _XBT_GNUC_FORMAT( arg_idx )
 # define _XBT_GNUC_NORETURN
 # define _XBT_GNUC_UNUSED
+# define _XBT_GNUC_CONSTRUCTOR
+# define _XBT_GNUC_DESTRUCTOR
+# define  _XBT_NEED_INIT_PRAGMA 1
 
 #endif /* !__GNUC__ */
 
index 6dc3f3b..a6e0c91 100644 (file)
@@ -75,7 +75,6 @@ void MSG_global_init(int *argc, char **argv)
     SIMIX_function_register_process_cleanup(__MSG_process_cleanup);
     SIMIX_function_register_process_kill(_MSG_process_kill_from_SIMIX);
   }
-  return;
 }
 
 /** \defgroup m_channel_management    Understanding channels
index a4ba715..6873353 100644 (file)
 #include "xbt_modinter.h"
 
 /* Module creation/destruction */
-void xbt_backtrace_init(void)
+void xbt_backtrace_preinit(void)
 {
 }
 
-void xbt_backtrace_exit(void)
+void xbt_backtrace_postexit(void)
 {
 }
 
index acdf28c..e5ddbb9 100644 (file)
 extern char **environ;          /* the environment, as specified by the opengroup */
 
 /* Module creation/destruction: nothing to do on linux */
-void xbt_backtrace_init(void)
+void xbt_backtrace_preinit(void)
 {
 }
 
-void xbt_backtrace_exit(void)
+void xbt_backtrace_postexit(void)
 {
 }
 
index edfc31b..e658216 100644 (file)
@@ -68,8 +68,8 @@ static HINSTANCE hlp_dbg_instance = NULL;
 static HANDLE process_handle = NULL;
 
 
-/* Module creation/destruction: nothing to do on linux */
-void xbt_backtrace_init(void)
+/* Module creation/destruction: initialize our tables */
+void xbt_backtrace_preinit(void)
 {
   process_handle = GetCurrentProcess();
 
@@ -130,7 +130,7 @@ void xbt_backtrace_init(void)
   }
 }
 
-void xbt_backtrace_exit(void)
+void xbt_backtrace_postexit(void)
 {
   if (!hlp_dbg_instance)
     return;
index 150bf69..d71f11b 100644 (file)
@@ -751,7 +751,7 @@ void xbt_dict_dump_sizes(xbt_dict_t dict)
  * Destroy the dict mallocators.
  * This is an internal XBT function called by xbt_exit().
  */
-void xbt_dict_exit(void)
+void xbt_dict_postexit(void)
 {
   if (dict_mallocator != NULL) {
     xbt_mallocator_free(dict_mallocator);
index 8cdd401..f2f95ca 100644 (file)
@@ -26,15 +26,10 @@ xbt_fifo_t xbt_fifo_new(void)
   xbt_fifo_t fifo;
   fifo = xbt_new0(struct xbt_fifo, 1);
 
-  if (item_mallocator == NULL) {
-    item_mallocator = xbt_mallocator_new(256,
-                                         fifo_item_mallocator_new_f,
-                                         fifo_item_mallocator_free_f,
-                                         fifo_item_mallocator_reset_f);
-  }
   return fifo;
 }
 
+
 /** Destructor
  * \param l poor victim
  *
@@ -510,12 +505,17 @@ xbt_fifo_item_t xbt_fifo_getPrevItem(xbt_fifo_item_t i)
   return xbt_fifo_get_prev_item(i);
 }
 
-/**
- * Destroy the fifo item mallocator.
- * This is an internal XBT function called by xbt_exit().
+/* Module init/exit handling the fifo item mallocator
+ * These are internal XBT functions called by xbt_preinit/postexit().
  */
-void xbt_fifo_exit(void)
-{
+void xbt_fifo_preinit(void) {
+  item_mallocator = xbt_mallocator_new(256,
+                                       fifo_item_mallocator_new_f,
+                                       fifo_item_mallocator_free_f,
+                                       fifo_item_mallocator_reset_f);
+}
+
+void xbt_fifo_postexit(void) {
   if (item_mallocator != NULL) {
     xbt_mallocator_free(item_mallocator);
     item_mallocator = NULL;
index e4e7a7d..269c7c0 100644 (file)
@@ -468,7 +468,6 @@ 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 */
-int _log_usable = 0;
 
 typedef struct {
   char *catname;
@@ -523,23 +522,23 @@ XBT_LOG_NEW_CATEGORY(bindings, "All bindings categories");
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(log, xbt,
                                 "Loggings from the logging mechanism itself");
 
+/* create the default appender and install it in the root category,
+   which were already created (damnit. Too slow little beetle) */
+void xbt_log_preinit(void) {
+  xbt_log_default_appender = xbt_log_appender_file_new(NULL);
+  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;
+}
+
 /** @brief Get all logging settings from the command line
  *
  * xbt_log_control_set() is called on each string we got from cmd line
  */
-void xbt_log_init(int *argc, char **argv)
-{
+void xbt_log_init(int *argc, char **argv) {
   int i, j;
   char *opt;
 
-  /* create the default appender and install it in the root category,
-     which were already created (damnit. Too slow little beetle) */
-  xbt_log_default_appender = xbt_log_appender_file_new(NULL);
-  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_usable = 1;
-
   //    _XBT_LOGV(log).threshold = xbt_log_priority_debug; /* uncomment to set the LOG category to debug directly */
 
   /* Set logs and init log submodule */
@@ -592,26 +591,17 @@ static void log_cat_exit(xbt_log_category_t cat)
     log_cat_exit(child);
 }
 
-void xbt_log_exit(void)
+void xbt_log_postexit(void)
 {
   VERB0("Exiting log");
   xbt_dynar_free(&xbt_log_settings);
   log_cat_exit(&_XBT_LOGV(XBT_LOG_ROOT_CAT));
-  _log_usable = 0;
 }
 
 void _xbt_log_event_log(xbt_log_event_t ev, const char *fmt, ...)
 {
 
   xbt_log_category_t cat = ev->cat;
-  if (!_log_usable) {
-    /* Make sure that the layouts have been malloced */
-    xbt_log_default_appender = xbt_log_appender_file_new(NULL);
-    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_usable = 1;
-  }
 
   va_start(ev->ap, fmt);
   va_start(ev->ap_copy, fmt);
index da053ee..337164d 100644 (file)
@@ -6,6 +6,7 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
+#include "xbt/misc.h"
 #include "time.h"               /* to seed the random generator */
 
 #include "xbt/sysdep.h"
@@ -45,13 +46,40 @@ XBT_LOG_EXTERNAL_CATEGORY(xbt_queue);
 XBT_LOG_EXTERNAL_CATEGORY(xbt_set);
 XBT_LOG_EXTERNAL_CATEGORY(xbt_sync_os);
 
-/** @brief Initialize the xbt mechanisms. */
-void xbt_init(int *argc, char **argv)
-{
-  xbt_initialized++;
 
-  if (xbt_initialized != 1)
-    return;
+/* Declare xbt_preinit and xbt_postexit as constructor/destructor of the library.
+ * This is crude and rather compiler-specific, unfortunately.
+ */
+static void xbt_preinit(void) _XBT_GNUC_CONSTRUCTOR;
+static void xbt_postexit(void) _XBT_GNUC_DESTRUCTOR;
+#ifdef _XBT_NEED_INIT_PRAGMA
+#pragma init (xbt_preinit)
+#pragma fini (xbt_postexit)
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+
+/* Dummy prototype to make gcc happy */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
+
+
+/* see also http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx */
+/* and http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
+  if (fdwReason == DLL_PROCESS_ATTACH) {
+    xbt_preinit();
+  } else if (fdwReason == DLL_PROCESS_DETACH) {
+    xbt_postexit();
+  }
+  return 1;
+}
+
+
+#endif
+
+static void xbt_preinit(void) {
+  xbt_log_preinit();
 
   /* Connect our log channels: that must be done manually under windows */
   XBT_LOG_CONNECT(graphxml_parse, xbt);
@@ -77,34 +105,45 @@ void xbt_init(int *argc, char **argv)
   XBT_LOG_CONNECT(xbt_set, xbt);
   XBT_LOG_CONNECT(xbt_sync_os, xbt);
 
+  xbt_fifo_preinit();
+
+  xbt_backtrace_preinit();
+  xbt_os_thread_mod_preinit();
+}
+
+static void xbt_postexit(void) {
+  xbt_os_thread_mod_postexit();
+  xbt_backtrace_postexit();
+
+  xbt_fifo_postexit();
+  xbt_dict_postexit();
+
+  xbt_log_postexit();
+
+  free(xbt_binary_name);
+}
+
+/** @brief Initialize the xbt mechanisms. */
+void xbt_init(int *argc, char **argv)
+{
+  xbt_assert0(xbt_initialized == 0, "xbt_init must be called only once");
+  xbt_initialized++;
+
   xbt_binary_name = xbt_strdup(argv[0]);
   srand((unsigned int) time(NULL));
   VERB0("Initialize XBT");
 
-  xbt_backtrace_init();
   xbt_log_init(argc, argv);
-  xbt_os_thread_mod_init();
 }
 
 /** @brief Finalize the xbt mechanisms. */
-void xbt_exit()
-{
-  xbt_initialized--;
-  if (xbt_initialized == 0) {
-    xbt_fifo_exit();
-    xbt_dict_exit();
-    xbt_os_thread_mod_exit();
-    xbt_log_exit();
-    xbt_backtrace_exit();
-    free(xbt_binary_name);
-  }
+void xbt_exit() {
 }
 
 
 /* these two functions belong to xbt/sysdep.h, which have no corresponding .c file */
 /** @brief like free, but you can be sure that it is a function  */
-XBT_PUBLIC(void) xbt_free_f(void *p)
-{
+XBT_PUBLIC(void) xbt_free_f(void *p) {
   free(p);
 }
 
index 55be50b..c2768de 100644 (file)
@@ -72,7 +72,7 @@ static void _os_thread_ex_terminate(xbt_ex_t * e)
   /* FIXME: there should be a configuration variable to choose to kill everyone or only this one */
 }
 
-void xbt_os_thread_mod_init(void)
+void xbt_os_thread_mod_preinit(void)
 {
   int errcode;
 
@@ -101,8 +101,7 @@ void xbt_os_thread_mod_init(void)
 
 }
 
-void xbt_os_thread_mod_exit(void)
-{
+void xbt_os_thread_mod_postexit(void) {
   /* FIXME: don't try to free our key on shutdown.
      Valgrind detects no leak if we don't, and whine if we try to */
   //   int errcode;
@@ -600,12 +599,12 @@ typedef struct xbt_os_thread_ {
 /* key to the TLS containing the xbt_os_thread_t structure */
 static unsigned long xbt_self_thread_key;
 
-void xbt_os_thread_mod_init(void)
+void xbt_os_thread_mod_preinit(void)
 {
   xbt_self_thread_key = TlsAlloc();
 }
 
-void xbt_os_thread_mod_exit(void)
+void xbt_os_thread_mod_postexit(void)
 {
 
   if (!TlsFree(xbt_self_thread_key))
index d91a955..6a86c13 100644 (file)
  */
 
 /* Mod_init/exit mecanism */
-void xbt_os_thread_mod_init(void)
+void xbt_os_thread_mod_preinit(void)
 {
 }
 
-void xbt_os_thread_mod_exit(void)
+void xbt_os_thread_mod_postexit(void)
 {
 }
 
index 7ad2c4f..87f3766 100644 (file)
 #include "xbt/misc.h"
 
 /* Modules definitions */
-void xbt_backtrace_init(void);
-void xbt_backtrace_exit(void);
+void xbt_backtrace_preinit(void);
+void xbt_backtrace_postexit(void);
 
+void xbt_log_preinit(void);
 void xbt_log_init(int *argc, char **argv);
-void xbt_log_exit(void);
-void xbt_fifo_exit(void);
-void xbt_dict_exit(void);
+void xbt_log_postexit(void);
 
-void xbt_os_thread_mod_init(void);
-void xbt_os_thread_mod_exit(void);
+void xbt_fifo_preinit(void);
+void xbt_fifo_postexit(void);
+void xbt_dict_postexit(void);
+
+void xbt_os_thread_mod_preinit(void);
+void xbt_os_thread_mod_postexit(void);
 
 #endif /* XBT_MODINTER_H */