aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c')
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c b/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c
new file mode 100644
index 0000000000..3809c915e0
--- /dev/null
+++ b/erts/emulator/test/erl_drv_thread_SUITE_data/tsd.c
@@ -0,0 +1,173 @@
+/* ``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 via the world wide web 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.
+ *
+ * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+ * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+ * AB. All Rights Reserved.''
+ *
+ * $Id$
+ */
+
+#include "testcase_driver.h"
+#include <stdio.h>
+
+#define NO_OF_THREADS 17
+#define NO_OF_KEYS 4711
+
+struct {
+ int alive;
+ ErlDrvTid tid;
+} test_thr[NO_OF_THREADS] = {0};
+
+struct {
+ int used;
+ ErlDrvTSDKey key;
+} test_key[NO_OF_KEYS] = {0};
+
+typedef struct {
+ int n;
+} thr_arg_t;
+
+static void *tf(void *vta)
+{
+ int i;
+ int thr_val = (((thr_arg_t *) vta)->n << 16);
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ erl_drv_tsd_set(test_key[i].key, (void *) (thr_val | i));
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ if (erl_drv_tsd_get(test_key[i].key) != ((void *) (thr_val | i)))
+ return (void *) 1;
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ erl_drv_tsd_set(test_key[i].key, NULL);
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ if (erl_drv_tsd_get(test_key[i].key) != NULL)
+ return (void *) 2;
+
+ return (void *) 3;
+}
+
+void
+thr_key_clnup(void)
+{
+ int i;
+ for (i = 0; i < NO_OF_KEYS; i++)
+ erl_drv_tsd_set(test_key[i].key, NULL);
+}
+
+void
+testcase_run(TestCaseState_t *tcs)
+{
+ int i, r;
+ thr_arg_t ta[NO_OF_THREADS];
+ ErlDrvSysInfo sinfo;
+
+ testcase_printf(tcs, "Initializing\n");
+
+ driver_system_info(&sinfo, sizeof(ErlDrvSysInfo));
+
+ for (i = 0; i < NO_OF_KEYS; i++) {
+ char name[100];
+ sprintf(name, "key %d", i);
+ r = erl_drv_tsd_key_create(name, &test_key[i].key);
+ ASSERT(tcs, r == 0);
+ test_key[i].used = 1;
+ }
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ erl_drv_tsd_set(test_key[i].key,
+ (void *) (((NO_OF_THREADS+1) << 16) | i));
+
+ if (!sinfo.thread_support)
+ testcase_printf(tcs, "No thread support; testing tsd in one thread\n");
+ else {
+ testcase_printf(tcs, "Creating %d threads\n", NO_OF_THREADS);
+
+ /* Create the threads */
+ for (i = 0; i < NO_OF_THREADS; i++) {
+ char name[100];
+ ta[i].n = 0;
+ sprintf(name, "thread %d", i);
+ r = erl_drv_thread_create(name,
+ &test_thr[i].tid,
+ tf,
+ (void *) &ta[i],
+ NULL);
+ ASSERT_CLNUP(tcs, r == 0, thr_key_clnup());
+ test_thr[i].alive = 1;
+ }
+ }
+
+ testcase_printf(tcs, "Testing tsd\n");
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ ASSERT_CLNUP(tcs,
+ ((void *) (((NO_OF_THREADS+1) << 16) | i)
+ == erl_drv_tsd_get(test_key[i].key)),
+ thr_key_clnup());
+
+ testcase_printf(tcs, "Joining threads\n");
+
+ if (sinfo.thread_support) {
+ /* Join the threads */
+ for (i = 0; i < NO_OF_THREADS; i++) {
+ void *res;
+ r = erl_drv_thread_join(test_thr[i].tid, &res);
+ test_thr[i].alive = 0;
+ ASSERT_CLNUP(tcs, r == 0, thr_key_clnup());
+ ASSERT_CLNUP(tcs, res == ((void *) 3), thr_key_clnup());
+ }
+ }
+
+ thr_key_clnup();
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ ASSERT(tcs, NULL == erl_drv_tsd_get(test_key[i].key));
+
+ testcase_printf(tcs, "Destroying keys\n");
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ if (test_key[i].used) {
+ test_key[i].used = 0;
+ erl_drv_tsd_key_destroy(test_key[i].key);
+ }
+
+ testcase_printf(tcs, "done\n");
+
+ if (!sinfo.thread_support)
+ testcase_succeeded(tcs, "No thread support; only one thread tested");
+}
+
+char *
+testcase_name(void)
+{
+ return "tsd";
+}
+
+void
+testcase_cleanup(TestCaseState_t *tcs)
+{
+ int i;
+ for (i = 0; i < NO_OF_THREADS; i++)
+ if (test_thr[i].alive) {
+ test_thr[i].alive = 0;
+ erl_drv_thread_join(test_thr[i].tid, NULL);
+ }
+
+ for (i = 0; i < NO_OF_KEYS; i++)
+ if (test_key[i].used) {
+ test_key[i].used = 0;
+ erl_drv_tsd_key_destroy(test_key[i].key);
+ }
+}