* 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>
/* 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.
#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 ) \
__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 )
# 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__ */
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
#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)
{
}
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)
{
}
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();
}
}
-void xbt_backtrace_exit(void)
+void xbt_backtrace_postexit(void)
{
if (!hlp_dbg_instance)
return;
* 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);
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
*
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;
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;
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 */
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);
/* 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"
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);
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);
}
/* 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;
}
-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;
/* 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))
*/
/* 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)
{
}
#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 */