From e0702d63ff71a32f733f7c1044b008ca60777e9b Mon Sep 17 00:00:00 2001 From: mquinson Date: Thu, 6 May 2010 23:41:44 +0000 Subject: [PATCH] Use library init/fini functions for xbt initialization git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7707 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- ChangeLog | 4 ++ include/xbt/log.h | 2 +- include/xbt/misc.h | 8 +++- src/msg/global.c | 1 - src/xbt/backtrace_dummy.c | 4 +- src/xbt/backtrace_linux.c | 4 +- src/xbt/backtrace_windows.c | 6 +-- src/xbt/dict.c | 2 +- src/xbt/fifo.c | 22 +++++----- src/xbt/log.c | 32 +++++---------- src/xbt/xbt_main.c | 81 +++++++++++++++++++++++++++---------- src/xbt/xbt_os_thread.c | 9 ++--- src/xbt/xbt_sg_stubs.c | 4 +- src/xbt_modinter.h | 17 ++++---- 14 files changed, 118 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7fb0258ac3..0e8f1ef768 100644 --- 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 diff --git a/include/xbt/log.h b/include/xbt/log.h index d22e627e04..1502558dd7 100644 --- a/include/xbt/log.h +++ b/include/xbt/log.h @@ -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. diff --git a/include/xbt/misc.h b/include/xbt/misc.h index 3b89b3ec06..5ee26611b4 100644 --- a/include/xbt/misc.h +++ b/include/xbt/misc.h @@ -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__ */ diff --git a/src/msg/global.c b/src/msg/global.c index 6dc3f3b073..a6e0c91816 100644 --- a/src/msg/global.c +++ b/src/msg/global.c @@ -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 diff --git a/src/xbt/backtrace_dummy.c b/src/xbt/backtrace_dummy.c index a4ba715b37..68733532a6 100644 --- a/src/xbt/backtrace_dummy.c +++ b/src/xbt/backtrace_dummy.c @@ -12,11 +12,11 @@ #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) { } diff --git a/src/xbt/backtrace_linux.c b/src/xbt/backtrace_linux.c index acdf28cdeb..e5ddbb9ab4 100644 --- a/src/xbt/backtrace_linux.c +++ b/src/xbt/backtrace_linux.c @@ -17,11 +17,11 @@ 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) { } diff --git a/src/xbt/backtrace_windows.c b/src/xbt/backtrace_windows.c index edfc31bfab..e65821630c 100644 --- a/src/xbt/backtrace_windows.c +++ b/src/xbt/backtrace_windows.c @@ -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; diff --git a/src/xbt/dict.c b/src/xbt/dict.c index 150bf69d00..d71f11b4f9 100644 --- a/src/xbt/dict.c +++ b/src/xbt/dict.c @@ -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); diff --git a/src/xbt/fifo.c b/src/xbt/fifo.c index 8cdd4018d5..f2f95ca958 100644 --- a/src/xbt/fifo.c +++ b/src/xbt/fifo.c @@ -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; diff --git a/src/xbt/log.c b/src/xbt/log.c index e4e7a7d037..269c7c05e1 100644 --- a/src/xbt/log.c +++ b/src/xbt/log.c @@ -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); diff --git a/src/xbt/xbt_main.c b/src/xbt/xbt_main.c index da053ee824..337164d3d7 100644 --- a/src/xbt/xbt_main.c +++ b/src/xbt/xbt_main.c @@ -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 + +/* 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); } diff --git a/src/xbt/xbt_os_thread.c b/src/xbt/xbt_os_thread.c index 55be50b3e4..c2768de3e8 100644 --- a/src/xbt/xbt_os_thread.c +++ b/src/xbt/xbt_os_thread.c @@ -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)) diff --git a/src/xbt/xbt_sg_stubs.c b/src/xbt/xbt_sg_stubs.c index d91a9553d8..6a86c13a9c 100644 --- a/src/xbt/xbt_sg_stubs.c +++ b/src/xbt/xbt_sg_stubs.c @@ -27,11 +27,11 @@ */ /* 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) { } diff --git a/src/xbt_modinter.h b/src/xbt_modinter.h index 7ad2c4fe8d..87f37666da 100644 --- a/src/xbt_modinter.h +++ b/src/xbt_modinter.h @@ -11,15 +11,18 @@ #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 */ -- 2.20.1