typedef struct {
guint64 new_object_count;
- size_t initialized_class_count;
- size_t generic_vtable_count;
+ gsize initialized_class_count;
+ gsize generic_vtable_count;
size_t used_class_count;
size_t method_count;
size_t class_vtable_size;
size_t class_static_data_size;
size_t generic_instance_count;
- size_t generic_class_count;
- size_t inflated_method_count;
+ gsize generic_class_count;
+ gsize inflated_method_count;
size_t inflated_method_count_2;
- size_t inflated_type_count;
+ gsize inflated_type_count;
size_t generics_metadata_size;
size_t delegate_creations;
size_t imt_tables_size;
#include <mono/utils/mono-logger-internals.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/unlocked.h>
#include <mono/utils/bsearch.h>
#include <mono/utils/checked-build.h>
}
}
- mono_stats.inflated_type_count++;
+ UnlockedIncrementSize (&mono_stats.inflated_type_count);
return inflated;
}
if (!inflated)
return type;
- mono_stats.inflated_type_count++;
+ UnlockedIncrementSize (&mono_stats.inflated_type_count);
return inflated;
}
return (MonoMethod*)cached;
}
- mono_stats.inflated_method_count++;
+ UnlockedIncrementSize (&mono_stats.inflated_method_count);
inflated_methods_size += sizeof (MonoMethodInflated);
return;
}
- mono_stats.generic_vtable_count ++;
+ UnlockedIncrementSize (&mono_stats.generic_vtable_count);
in_setup = g_list_prepend (in_setup, klass);
if (mono_class_is_ginst (klass)) {
goto leave;
}
- mono_stats.initialized_class_count++;
+ UnlockedIncrementSize (&mono_stats.initialized_class_count);
if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic) {
MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
return !mono_class_has_failure (klass);
}
- mono_stats.initialized_class_count++;
+ UnlockedIncrementSize (&mono_stats.initialized_class_count);
if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic)
- mono_stats.generic_class_count++;
+ UnlockedIncrementSize (&mono_stats.generic_class_count);
if (mono_class_is_ginst (klass) || image_is_dynamic (klass->image) || !klass->type_token || (has_cached_info && !cached_info.has_nested_classes))
klass->nested_classes_inited = TRUE;
checked-build.h \
os-event.h \
refcount.h \
- w32api.h
+ w32api.h \
+ unlocked.h
arch_sources =
#define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
-/* Used to tell clang's ThreadSanitizer to not report data races that occur within a certain function */
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
-#define MONO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize("thread")))
+#define MONO_HAS_CLANG_THREAD_SANITIZER 1
#else
-#define MONO_NO_SANITIZE_THREAD
+#define MONO_HAS_CLANG_THREAD_SANITIZER 0
+#endif
+#else
+#define MONO_HAS_CLANG_THREAD_SANITIZER 0
#endif
+
+/* Used to tell Clang's ThreadSanitizer to not report data races that occur within a certain function */
+#if MONO_HAS_CLANG_THREAD_SANITIZER
+#define MONO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize("thread")))
#else
#define MONO_NO_SANITIZE_THREAD
#endif
--- /dev/null
+/**
+ * \file
+ * Contains inline functions to explicitly mark data races that should not be changed.
+ * This way, instruments like Clang's ThreadSanitizer can be told to ignore very specific instructions.
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#ifndef _UNLOCKED_H_
+#define _UNLOCKED_H_
+
+#include <glib.h>
+#include <mono/utils/mono-compiler.h>
+
+#if MONO_HAS_CLANG_THREAD_SANITIZER
+#define MONO_UNLOCKED_ATTRS MONO_NO_SANITIZE_THREAD MONO_NEVER_INLINE static
+#else
+#define MONO_UNLOCKED_ATTRS MONO_ALWAYS_INLINE static inline
+#endif
+
+MONO_UNLOCKED_ATTRS
+gint32
+UnlockedIncrement (gint32 *val)
+{
+ return ++*val;
+}
+
+MONO_UNLOCKED_ATTRS
+gint64
+UnlockedIncrement64 (gint64 *val)
+{
+ return ++*val;
+}
+
+MONO_UNLOCKED_ATTRS
+gsize
+UnlockedIncrementSize (gsize *val)
+{
+ return ++*val;
+}
+
+#endif /* _UNLOCKED_H_ */
<ClInclude Include="..\mono\utils\strenc.h" />\r
<ClInclude Include="..\mono\utils\valgrind.h" />\r
<ClInclude Include="..\mono\utils\atomic.h" />\r
+ <ClInclude Include="..\mono\utils\unlocked.h" />
<ClInclude Include="..\mono\utils\mono-hwcap.h" />\r
<ClInclude Include="..\mono\utils\mono-hwcap-x86.h" />\r
<ClInclude Include="..\mono\utils\bsearch.h" />\r
<ClInclude Include="..\mono\utils\os-event.h">\r
<Filter>Header Files</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\mono\utils\unlocked.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>\r
<ItemGroup>\r
<Filter Include="Header Files">\r