aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/alloc_SUITE_data/cpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/alloc_SUITE_data/cpool.c')
-rw-r--r--erts/emulator/test/alloc_SUITE_data/cpool.c157
1 files changed, 157 insertions, 0 deletions
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);
+}