From 66a80a7ab735a22249ffbbb7c88eccebba906194 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 21 Jan 2016 19:53:59 +0100
Subject: erts: Add checks for thread safe allocation

Assert thread unsafe allocator is only created on non-smp
and only called by the main thread.

Removed test of unsafe allocator in custom thread.
---
 erts/emulator/beam/erl_alloc.c                | 12 ++++++++++--
 erts/emulator/beam/erl_alloc_util.c           |  5 +++++
 erts/emulator/beam/erl_init.c                 | 11 ++++++-----
 erts/emulator/beam/global.h                   |  3 +++
 erts/emulator/test/alloc_SUITE_data/threads.c | 17 +----------------
 5 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 5544712e8d..e7523ac989 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -968,6 +968,10 @@ set_au_allocator(ErtsAlcType_t alctr_n, struct au_init *init, int ncpu)
     else
 #endif
     {
+#ifdef ERTS_SMP
+        erl_exit(ERTS_ABORT_EXIT, "%salloc is not thread safe\n",
+                 init->init.util.name_prefix);
+#else
 	af->alloc = erts_alcu_alloc;
 	if (init->init.util.fix_type_size)
 	    af->realloc = erts_realloc_fixed_size;
@@ -976,6 +980,7 @@ set_au_allocator(ErtsAlcType_t alctr_n, struct au_init *init, int ncpu)
 	else
 	    af->realloc = erts_alcu_realloc;
 	af->free = erts_alcu_free;
+#endif
     }
     af->extra	= NULL;
     ai->alloc_util	= 1;
@@ -3402,8 +3407,11 @@ UWord erts_alc_test(UWord op, UWord a1, UWord a2, UWord a3)
 	    init.enable = 1;
 	    init.atype = GOODFIT;
 	    init.init.util.name_prefix = (char *) a1;
-	    init.init.util.ts = a2 ? 1 : 0;
-
+#ifdef ERTS_SMP
+	    init.init.util.ts = 1;
+#else
+            init.init.util.ts = a2 ? 1 : 0;
+#endif
 	    if ((char **) a3) {
 		char **argv = (char **) a3;
 		int i = 0;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index eedfd1e13d..3230b6ef34 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -5337,6 +5337,11 @@ do_erts_alcu_alloc(ErtsAlcType_t type, void *extra, Uint size)
 void *erts_alcu_alloc(ErtsAlcType_t type, void *extra, Uint size)
 {
     void *res;
+#ifdef ERTS_SMP
+    ASSERT(!"This is not thread safe");
+#elif defined(USE_THREADS)
+    ASSERT(erts_equal_tids(erts_main_thread, erts_thr_self()));
+#endif
     res = do_erts_alcu_alloc(type, extra, size);
     DEBUG_CHECK_ALIGNMENT(res);
     return res;
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 42aca726bf..39957eb58b 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -152,7 +152,7 @@ volatile int erts_writing_erl_crash_dump = 0;
 int erts_initialized = 0;
 
 #if defined(USE_THREADS) && !defined(ERTS_SMP)
-static erts_tid_t main_thread;
+erts_tid_t erts_main_thread;
 #endif
 
 int erts_use_sender_punish;
@@ -744,6 +744,10 @@ early_init(int *argc, char **argv) /*
     char envbuf[21]; /* enough for any 64-bit integer */
     size_t envbufsz;
 
+#if defined(USE_THREADS) && !defined(ERTS_SMP)
+    erts_main_thread = erts_thr_self();
+#endif
+
     erts_save_emu_args(*argc, argv);
 
     erts_sched_compact_load = 1;
@@ -797,9 +801,6 @@ early_init(int *argc, char **argv) /*
 			       (erts_aint32_t) ((Uint16) -1));
 
     erts_pre_init_process();
-#if defined(USE_THREADS) && !defined(ERTS_SMP)
-    main_thread = erts_thr_self();
-#endif
 
     /*
      * We need to know the number of schedulers to use before we
@@ -2285,7 +2286,7 @@ system_cleanup(int flush_async)
     if (!flush_async
 	|| !erts_initialized
 #if defined(USE_THREADS) && !defined(ERTS_SMP)
-	|| !erts_equal_tids(main_thread, erts_thr_self())
+	|| !erts_equal_tids(erts_main_thread, erts_thr_self())
 #endif
 	)
 	return;
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 3f5925765d..ad9fdfc878 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1168,6 +1168,9 @@ extern ErtsModifiedTimings erts_modified_timings[];
 extern int erts_no_line_info;
 extern Eterm erts_error_logger_warnings;
 extern int erts_initialized;
+#if defined(USE_THREADS) && !defined(ERTS_SMP)
+extern erts_tid_t erts_main_thread;
+#endif
 extern int erts_compat_rel;
 extern int erts_use_sender_punish;
 void erts_short_init(void);
diff --git a/erts/emulator/test/alloc_SUITE_data/threads.c b/erts/emulator/test/alloc_SUITE_data/threads.c
index 2f5f841e3d..44d982b6c7 100644
--- a/erts/emulator/test/alloc_SUITE_data/threads.c
+++ b/erts/emulator/test/alloc_SUITE_data/threads.c
@@ -96,16 +96,11 @@ static void fail(int t_no, char *frmt, ...)
     exit_thread(t_no, 0);
 }
 
-static Allctr_t *alloc_not_ts = NULL;
 static Allctr_t *alloc_ts_1 = NULL;
 static Allctr_t *alloc_ts_2 = NULL;
 
 static void stop_allocators(void)
 {
-    if (alloc_not_ts) {
-	STOP_ALC(alloc_not_ts);
-	alloc_not_ts = NULL;
-    }
     if (alloc_ts_1) {
 	STOP_ALC(alloc_ts_1);
 	alloc_ts_1 = NULL;
@@ -155,7 +150,6 @@ testcase_run(TestCaseState_t *tcs)
     if (!IS_THREADS_ENABLED)
 	testcase_skipped(tcs, "Threads not enabled");
 
-    alloc_not_ts = NULL;
     alloc_ts_1 = NULL;
     alloc_ts_2 = NULL;
 
@@ -163,9 +157,6 @@ testcase_run(TestCaseState_t *tcs)
 
     sprintf(sbct_buf, "%d", SBC_THRESHOLD/1024);
     
-    memcpy((void *) argv, argv_org, sizeof(argv_org));
-    alloc_not_ts = START_ALC("threads_not_ts", 0, argv);
-    ASSERT(tcs, alloc_not_ts);
     memcpy((void *) argv, argv_org, sizeof(argv_org));
     alloc_ts_1 = START_ALC("threads_ts_1", 1, argv);
     ASSERT(tcs, alloc_ts_1);
@@ -173,7 +164,6 @@ testcase_run(TestCaseState_t *tcs)
     alloc_ts_2 = START_ALC("threads_ts_2", 1, argv);
     ASSERT(tcs, alloc_ts_2);
 
-    ASSERT(tcs, !IS_ALLOC_THREAD_SAFE(alloc_not_ts));
     ASSERT(tcs, IS_ALLOC_THREAD_SAFE(alloc_ts_1));
     ASSERT(tcs, IS_ALLOC_THREAD_SAFE(alloc_ts_2));
 
@@ -190,12 +180,7 @@ testcase_run(TestCaseState_t *tcs)
 
 	threads[i].arg.no_ops_per_bl = NO_OF_OPS_PER_BL;
 
-	if (i == 1) {
-	    alc = "threads_not_ts";
-	    threads[i].arg.no_ops_per_bl *= 2;
-	    threads[i].arg.a = alloc_not_ts;
-	}
-	else if (i % 2 == 0) {
+	if (i % 2 == 0) {
 	    alc = "threads_ts_1";
 	    threads[i].arg.a = alloc_ts_1;
 	}
-- 
cgit v1.2.3


From e9d6797e15e687828e5ef0d33fb790181d657779 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 21 Jan 2016 19:54:46 +0100
Subject: erts: Fix faulty assert for non-smp

---
 erts/emulator/beam/erl_message.c | 2 +-
 erts/emulator/beam/sys.h         | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index b3e74e3e6a..88efb2c59f 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -1504,7 +1504,7 @@ erts_factory_message_create(ErtsHeapFactory* factory,
     }
 
     if (on_heap) {
-	ASSERT(*proc_locksp & ERTS_PROC_LOCK_MAIN);
+	ERTS_SMP_ASSERT(*proc_locksp & ERTS_PROC_LOCK_MAIN);
 	ASSERT(ohp == &proc->off_heap);
 	factory->mode = FACTORY_HALLOC;
 	factory->p = proc;
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 53f8313daa..37fcfd1c52 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -196,6 +196,12 @@ __decl_noreturn void __noreturn erl_assert_error(const char* expr, const char *f
 #  define ASSERT(e) ((void) 1)
 #endif
 
+#ifdef ERTS_SMP
+#  define ERTS_SMP_ASSERT(e) ASSERT(e)
+#else
+#  define ERTS_SMP_ASSERT(e) ((void)1)
+#endif
+
 /* ERTS_UNDEF can be used to silence false warnings about
  * "variable may be used uninitialized" while keeping the variable
  * marked as undefined by valgrind.
-- 
cgit v1.2.3