Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Comment is not relevant anymore.
[simgrid.git] / src / xbt / dict.cpp
index af97e2d..f1e73d3 100644 (file)
@@ -1,6 +1,6 @@
 /* dict - a generic dictionary, variation over hash table                   */
 
-/* Copyright (c) 2004-2020. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved.          */
 
 /* 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. */
@@ -8,20 +8,40 @@
 #include "xbt/dict.h"
 #include "dict_private.h"
 #include "simgrid/Exception.hpp"
-#include "src/xbt_modinter.h"
 #include "xbt/ex.h"
 #include "xbt/log.h"
 #include "xbt/mallocator.h"
 #include "xbt/str.h"
 #include "xbt/string.hpp"
 
+#include <algorithm>
 #include <cstdio>
 #include <cstring>
+#include <mutex>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_dict, xbt, "Dictionaries provide the same functionalities as hash tables");
 
 constexpr int MAX_FILL_PERCENT = 80;
 
+/** Handle the dict mallocators init/fini cycle. */
+static void xbt_dict_postexit()
+{
+  if (dict_elm_mallocator != nullptr) {
+    xbt_mallocator_free(dict_elm_mallocator);
+    dict_elm_mallocator = nullptr;
+  }
+}
+static void xbt_dict_preinit()
+{
+  static std::mutex init_mutex;
+  const std::scoped_lock lock(init_mutex);
+  if (dict_elm_mallocator == nullptr) {
+    dict_elm_mallocator =
+        xbt_mallocator_new(256, dict_elm_mallocator_new_f, dict_elm_mallocator_free_f, dict_elm_mallocator_reset_f);
+    atexit(xbt_dict_postexit);
+  }
+}
+
 /**
  * @brief Constructor
  * @param free_ctn function to call with (@a data as argument) when @a data is removed from the dictionary
@@ -33,7 +53,7 @@ constexpr int MAX_FILL_PERCENT = 80;
  */
 xbt_dict_t xbt_dict_new_homogeneous(void_f_pvoid_t free_ctn)
 {
-  xbt_dict_preinit();
+  xbt_dict_preinit(); // Make sure that the module is intialized
 
   xbt_dict_t dict;
 
@@ -89,8 +109,8 @@ static void xbt_dict_rehash(xbt_dict_t dict)
   const unsigned oldsize = dict->table_size + 1;
   unsigned newsize = oldsize * 2;
 
-  auto* newtable = static_cast<xbt_dictelm_t*>(xbt_realloc((char*)dict->table, newsize * sizeof(xbt_dictelm_t)));
-  memset(&newtable[oldsize], 0, oldsize * sizeof(xbt_dictelm_t)); /* zero second half */
+  auto* newtable = static_cast<xbt_dictelm_t*>(xbt_realloc(dict->table, newsize * sizeof(xbt_dictelm_t)));
+  std::fill(newtable + oldsize, newtable + newsize, nullptr); /* zero second half */
   newsize--;
   dict->table_size = newsize;
   dict->table      = newtable;
@@ -303,27 +323,3 @@ int xbt_dict_is_empty(const_xbt_dict_t dict)
 {
   return not dict || (xbt_dict_length(dict) == 0);
 }
-
-/**
- * Create the dict mallocators.
- * This is an internal XBT function called during the lib initialization.
- * It can be used several times to recreate the mallocator, for example when you switch to MC mode
- */
-void xbt_dict_preinit()
-{
-  if (dict_elm_mallocator == nullptr)
-    dict_elm_mallocator = xbt_mallocator_new(256, dict_elm_mallocator_new_f, dict_elm_mallocator_free_f,
-      dict_elm_mallocator_reset_f);
-}
-
-/**
- * Destroy the dict mallocators.
- * This is an internal XBT function during the lib initialization
- */
-void xbt_dict_postexit()
-{
-  if (dict_elm_mallocator != nullptr) {
-    xbt_mallocator_free(dict_elm_mallocator);
-    dict_elm_mallocator = nullptr;
-  }
-}