From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- .../test/obsolete_SUITE_data/erl_threads.c | 302 +++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 erts/emulator/test/obsolete_SUITE_data/erl_threads.c (limited to 'erts/emulator/test/obsolete_SUITE_data/erl_threads.c') diff --git a/erts/emulator/test/obsolete_SUITE_data/erl_threads.c b/erts/emulator/test/obsolete_SUITE_data/erl_threads.c new file mode 100644 index 0000000000..27a5163121 --- /dev/null +++ b/erts/emulator/test/obsolete_SUITE_data/erl_threads.c @@ -0,0 +1,302 @@ +/* ``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" + +#ifndef __WIN32__ + +#define NO_OF_THREADS 2 + +#include +#include + +static int die; +static int cw_passed; +static int res_tf0; +static int res_tf1; +static erl_mutex_t mtx; +static erl_cond_t cnd; +static erl_thread_t tid[NO_OF_THREADS]; +static int need_join[NO_OF_THREADS]; + +typedef struct { + int n; +} thr_arg_t; + + +static void *tf0(void *vta) +{ + int r; + + if (((thr_arg_t *) vta)->n != 0) + goto fail; + + r = erts_mutex_lock(mtx); + if (r != 0) { + erts_mutex_unlock(mtx); + goto fail; + } + + r = erts_cond_wait(cnd, mtx); + if (r != 0 || die) { + erts_mutex_unlock(mtx); + goto fail; + } + + cw_passed++; + + r = erts_cond_wait(cnd, mtx); + if (r != 0 || die) { + erts_mutex_unlock(mtx); + goto fail; + } + + cw_passed++; + + r = erts_mutex_unlock(mtx); + if (r != 0) + goto fail; + + res_tf0 = 0; + + return (void *) &res_tf0; + + fail: + return NULL; +} + + +static void *tf1(void *vta) +{ + int r; + + if (((thr_arg_t *) vta)->n != 1) + goto fail; + + r = erts_mutex_lock(mtx); + if (r != 0) { + erts_mutex_unlock(mtx); + goto fail; + } + + r = erts_cond_wait(cnd, mtx); + if (r != 0 || die) { + erts_mutex_unlock(mtx); + goto fail; + } + + cw_passed++; + + r = erts_cond_wait(cnd, mtx); + if (r != 0 || die) { + erts_mutex_unlock(mtx); + goto fail; + } + + cw_passed++; + + r = erts_mutex_unlock(mtx); + if (r != 0) + goto fail; + + res_tf1 = 1; + + erts_thread_exit((void *) &res_tf1); + + res_tf1 = 4711; + + fail: + return NULL; +} + +#endif /* #ifndef __WIN32__ */ + +void +testcase_run(TestCaseState_t *tcs) +{ +#ifdef __WIN32__ + testcase_skipped(tcs, "Nothing to test; not supported on windows."); +#else + int i, r; + void *tres[NO_OF_THREADS]; + thr_arg_t ta[NO_OF_THREADS]; + erl_thread_t t1; + + die = 0; + cw_passed = 0; + + for (i = 0; i < NO_OF_THREADS; i++) + need_join[i] = 0; + + res_tf0 = 17; + res_tf1 = 17; + + cnd = mtx = NULL; + + /* Create mutex and cond */ + mtx = erts_mutex_create(); + ASSERT(tcs, mtx); + cnd = erts_cond_create(); + ASSERT(tcs, cnd); + + /* Create the threads */ + ta[0].n = 0; + r = erts_thread_create(&tid[0], tf0, (void *) &ta[0], 0); + ASSERT(tcs, r == 0); + need_join[0] = 1; + + ta[1].n = 1; + r = erts_thread_create(&tid[1], tf1, (void *) &ta[1], 0); + ASSERT(tcs, r == 0); + need_join[1] = 1; + + /* Make sure the threads waits on cond wait */ + sleep(1); + + r = erts_mutex_lock(mtx); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + ASSERT_CLNUP(tcs, cw_passed == 0, (void) erts_mutex_unlock(mtx)); + + + /* Let one thread pass one cond wait */ + r = erts_cond_signal(cnd); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + r = erts_mutex_unlock(mtx); + ASSERT(tcs, r == 0); + + sleep(1); + + r = erts_mutex_lock(mtx); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + ASSERT_CLNUP(tcs, cw_passed == 1, (void) erts_mutex_unlock(mtx)); + + + /* Let both threads pass one cond wait */ + r = erts_cond_broadcast(cnd); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + r = erts_mutex_unlock(mtx); + ASSERT(tcs, r == 0); + + sleep(1); + + r = erts_mutex_lock(mtx); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + ASSERT_CLNUP(tcs, cw_passed == 3, (void) erts_mutex_unlock(mtx)); + + + /* Let the thread that only have passed one cond wait pass the other one */ + r = erts_cond_signal(cnd); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + r = erts_mutex_unlock(mtx); + ASSERT(tcs, r == 0); + + sleep(1); + + r = erts_mutex_lock(mtx); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + ASSERT_CLNUP(tcs, cw_passed == 4, (void) erts_mutex_unlock(mtx)); + + /* Both threads should have passed both cond waits and exited; + join them and check returned values */ + + r = erts_thread_join(tid[0], &tres[0]); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + need_join[0] = 0; + + ASSERT_CLNUP(tcs, tres[0] == &res_tf0, (void) erts_mutex_unlock(mtx)); + ASSERT_CLNUP(tcs, res_tf0 == 0, (void) erts_mutex_unlock(mtx)); + + r = erts_thread_join(tid[1], &tres[1]); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + need_join[1] = 0; + + ASSERT_CLNUP(tcs, tres[1] == &res_tf1, (void) erts_mutex_unlock(mtx)); + ASSERT_CLNUP(tcs, res_tf1 == 1, (void) erts_mutex_unlock(mtx)); + + /* Test signaling when noone waits */ + + r = erts_cond_signal(cnd); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + /* Test broadcasting when noone waits */ + + r = erts_cond_broadcast(cnd); + ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); + + /* erts_cond_timedwait() not supported anymore */ + r = erts_cond_timedwait(cnd, mtx, 1000); + ASSERT_CLNUP(tcs, r != 0, (void) erts_mutex_unlock(mtx)); + ASSERT_CLNUP(tcs, + strcmp(erl_errno_id(r), "enotsup") == 0, + (void) erts_mutex_unlock(mtx)); + + r = erts_mutex_unlock(mtx); + ASSERT(tcs, r == 0); + + r = erts_mutex_destroy(mtx); + ASSERT(tcs, r == 0); + mtx = NULL; + + r = erts_cond_destroy(cnd); + ASSERT(tcs, r == 0); + cnd = NULL; + + /* ... */ + t1 = erts_thread_self(); + + if (cw_passed == 4711) { + /* We don't want to execute this just check that the + symbol/symbols is/are defined */ + erts_thread_kill(t1); + } + +#endif /* #ifndef __WIN32__ */ +} + +char * +testcase_name(void) +{ + return "erl_threads"; +} + +void +testcase_cleanup(TestCaseState_t *tcs) +{ + int i; + for (i = 0; i < NO_OF_THREADS; i++) { + if (need_join[i]) { + erts_mutex_lock(mtx); + die = 1; + erts_cond_broadcast(cnd); + erts_mutex_unlock(mtx); + erts_thread_join(tid[1], NULL); + } + } + if (mtx) + erts_mutex_destroy(mtx); + if (cnd) + erts_cond_destroy(cnd); +} + -- cgit v1.2.3