aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/alloc_SUITE.erl9
-rw-r--r--erts/emulator/test/alloc_SUITE_data/Makefile.src3
-rw-r--r--erts/emulator/test/alloc_SUITE_data/allocator_test.h7
-rw-r--r--erts/emulator/test/alloc_SUITE_data/cpool.c157
4 files changed, 173 insertions, 3 deletions
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 22b5d93983..33abd45982 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -28,7 +28,8 @@
bucket_index/1,
bucket_mask/1,
rbtree/1,
- mseg_clear_cache/1]).
+ mseg_clear_cache/1,
+ cpool/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -40,7 +41,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic, coalesce, threads, realloc_copy, bucket_index,
- bucket_mask, rbtree, mseg_clear_cache].
+ bucket_mask, rbtree, mseg_clear_cache, cpool].
groups() ->
[].
@@ -105,6 +106,10 @@ mseg_clear_cache(suite) -> [];
mseg_clear_cache(doc) -> [];
mseg_clear_cache(Cfg) -> ?line drv_case(Cfg).
+cpool(suite) -> [];
+cpool(doc) -> [];
+cpool(Cfg) -> ?line drv_case(Cfg).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
%% Internal functions %%
diff --git a/erts/emulator/test/alloc_SUITE_data/Makefile.src b/erts/emulator/test/alloc_SUITE_data/Makefile.src
index 035415d73e..1d4286e671 100644
--- a/erts/emulator/test/alloc_SUITE_data/Makefile.src
+++ b/erts/emulator/test/alloc_SUITE_data/Makefile.src
@@ -23,7 +23,8 @@ TEST_DRVS = basic@dll@ \
bucket_index@dll@ \
bucket_mask@dll@ \
rbtree@dll@ \
- mseg_clear_cache@dll@
+ mseg_clear_cache@dll@ \
+ cpool@dll@
CC = @CC@
LD = @LD@
diff --git a/erts/emulator/test/alloc_SUITE_data/allocator_test.h b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
index f1d6d59211..c37b074f93 100644
--- a/erts/emulator/test/alloc_SUITE_data/allocator_test.h
+++ b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
@@ -78,6 +78,12 @@ typedef void* erts_cond;
#define BLK_TO_MBC(B) ((Carrier_t *) ALC_TEST1(0x01c, (B)))
#define ADD_MBC(A, C) ((void) ALC_TEST2(0x01d, (A), (C)))
#define REMOVE_MBC(A, C) ((void) ALC_TEST2(0x01e, (A), (C)))
+#define ZERO_CRR_SIZE ((Ulong) ALC_TEST0(0x01f))
+#define ZERO_CRR_INIT(A,B) ((Carrier_t *) ALC_TEST2(0x020, (A), (B)))
+#define CPOOL_INSERT(A,B) ((Carrier_t *) ALC_TEST2(0x021, (A), (B)))
+#define CPOOL_DELETE(A,B) ((Carrier_t *) ALC_TEST2(0x022, (A), (B)))
+#define CPOOL_IS_EMPTY(A) ((int) ALC_TEST1(0x023, (A)))
+#define CPOOL_IS_IN_POOL(A,B) ((int) ALC_TEST2(0x024, (A), (B)))
/* From erl_goodfit_alloc.c */
#define BKT_IX(A, S) ((Ulong) ALC_TEST2(0x100, (A), (S)))
@@ -133,5 +139,6 @@ typedef void* erts_cond;
#define THR_CREATE(F, A) ((erts_thread) ALC_TEST2(0xf10, (F), (A)))
#define THR_JOIN(T) ((void) ALC_TEST1(0xf11, (T)))
#define THR_EXIT(R) ((void) ALC_TEST1(0xf12, (R)))
+#define IS_SMP_ENABLED ((int) ALC_TEST0(0xf13))
#endif
diff --git a/erts/emulator/test/alloc_SUITE_data/cpool.c b/erts/emulator/test/alloc_SUITE_data/cpool.c
new file mode 100644
index 0000000000..276ed7be04
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/cpool.c
@@ -0,0 +1,157 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2013. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+
+#ifndef __WIN32__
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "testcase_driver.h"
+#include "allocator_test.h"
+
+#define FATAL_ASSERT(A) \
+ ((void) ((A) \
+ ? 1 \
+ : (fatal_assert_failed(#A, \
+ (char *) __FILE__, \
+ __LINE__), \
+ 0)))
+
+static void
+fatal_assert_failed(char* expr, char* file, int line)
+{
+ fflush(stdout);
+ fprintf(stderr, "%s:%d: Assertion failed: %s\n",
+ file, line, expr);
+ fflush(stderr);
+ abort();
+}
+
+#define TEST_NO_THREADS 10
+#define TEST_NO_CARRIERS_PER_THREAD 100000
+#define TEST_CARRIERS_OFFSET 5
+
+static Allctr_t *alloc = NULL;
+
+static void stop_allocator(void)
+{
+ if (alloc) {
+ STOP_ALC(alloc);
+ alloc = NULL;
+ }
+}
+
+
+void *thread_func(void *arg);
+
+char *
+testcase_name(void)
+{
+ return "cpool";
+}
+
+void
+testcase_cleanup(TestCaseState_t *tcs)
+{
+ stop_allocator();
+}
+
+void *
+thread_func(void *arg)
+{
+ Carrier_t *crr = (Carrier_t *) arg;
+ int i;
+
+ for (i = 0; i < (TEST_NO_CARRIERS_PER_THREAD+TEST_CARRIERS_OFFSET); i++) {
+ int d;
+ if (i < TEST_NO_CARRIERS_PER_THREAD) {
+ CPOOL_INSERT(alloc, crr[i]);
+ if ((i & 0x7) == 0)
+ FATAL_ASSERT(CPOOL_IS_IN_POOL(alloc, crr[i]));
+ }
+ d = i-TEST_CARRIERS_OFFSET;
+ if (d >= 0) {
+ CPOOL_DELETE(alloc, crr[d]);
+ if ((d & 0x7) == 0)
+ FATAL_ASSERT(!CPOOL_IS_IN_POOL(alloc, crr[d]));
+ }
+ }
+ for (i = 0; i < TEST_NO_CARRIERS_PER_THREAD; i++)
+ FATAL_ASSERT(!CPOOL_IS_IN_POOL(alloc, crr[i]));
+ return NULL;
+}
+
+static struct {
+ erts_thread tid;
+ Carrier_t *crr[TEST_NO_CARRIERS_PER_THREAD];
+} threads[TEST_NO_THREADS] = {{0}};
+
+void
+testcase_run(TestCaseState_t *tcs)
+{
+ int no_threads, t, c;
+ char *block, *p;
+ Ulong zcrr_sz;
+
+ if (!IS_SMP_ENABLED)
+ testcase_skipped(tcs, "No SMP support");
+
+ alloc = START_ALC("Zero carrier allocator", 1, NULL);
+
+ zcrr_sz = ZERO_CRR_SIZE;
+
+ block = p = ALLOC(alloc, zcrr_sz*TEST_NO_THREADS*TEST_NO_CARRIERS_PER_THREAD);
+
+ ASSERT(tcs, block != NULL);
+
+ for (t = 0; t < TEST_NO_THREADS; t++) {
+ for (c = 0; c < TEST_NO_CARRIERS_PER_THREAD; c++) {
+ Carrier_t *crr = (Carrier_t *) p;
+ p += zcrr_sz;
+ ZERO_CRR_INIT(alloc, crr);
+ threads[t].crr[c] = crr;
+ }
+ }
+
+ no_threads = 0;
+ for (t = 0; t < TEST_NO_THREADS; t++) {
+ threads[t].tid = THR_CREATE(thread_func, (void *) threads[t].crr);
+ if (threads[t].tid) {
+ testcase_printf(tcs, "Successfully created thread %d\n", t);
+ no_threads++;
+ }
+ else {
+ testcase_printf(tcs, "Failed to create thread %d\n", t);
+ break;
+ }
+ }
+
+ for (t = 0; t < no_threads; t++)
+ THR_JOIN(threads[t].tid);
+
+ FATAL_ASSERT(CPOOL_IS_EMPTY(alloc));
+
+ FREE(alloc, block);
+
+ ASSERT(tcs, no_threads == TEST_NO_THREADS);
+}