~clint-fewbar/ubuntu/precise/erlang/merge-15b

« back to all changes in this revision

Viewing changes to erts/emulator/test/erl_drv_thread_SUITE_data/basic.c

  • Committer: Elliot Murphy
  • Date: 2009-12-22 02:56:21 UTC
  • mfrom: (3.3.5 sid)
  • Revision ID: elliot@elliotmurphy.com-20091222025621-qv3rja8gbpiabkbe
Tags: 1:13.b.3-dfsg-2ubuntu1
* Merge with Debian testing; remaining Ubuntu changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to. (LP #438365)
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
* Fixed dialyzer(1) manpage which was placed into section 3 and conflicted
  with dialyzer(3erl).
* New upstream release (it adds a new binary package erlang-erl-docgen).
* Refreshed patches, removed most of emacs.patch which is applied upstream.
* Linked run_test binary from erlang-common-test package to /usr/bin.
* Fixed VCS headers in debian/control.
* Moved from prebuilt manpages to generated from sources. This adds
  erlang-manpages binary package and xsltproc build dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ``The contents of this file are subject to the Erlang Public License,
 
2
 * Version 1.1, (the "License"); you may not use this file except in
 
3
 * compliance with the License. You should have received a copy of the
 
4
 * Erlang Public License along with this software. If not, it can be
 
5
 * retrieved via the world wide web at http://www.erlang.org/.
 
6
 * 
 
7
 * Software distributed under the License is distributed on an "AS IS"
 
8
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
9
 * the License for the specific language governing rights and limitations
 
10
 * under the License.
 
11
 * 
 
12
 * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
 
13
 * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
 
14
 * AB. All Rights Reserved.''
 
15
 * 
 
16
 *     $Id$
 
17
 */
 
18
 
 
19
#include "testcase_driver.h"
 
20
 
 
21
#ifdef __WIN32__
 
22
#include <windows.h>
 
23
#else
 
24
#include <unistd.h>
 
25
#endif
 
26
#include <errno.h>
 
27
 
 
28
#define NO_OF_THREADS 2
 
29
 
 
30
static int die;
 
31
static int cw_passed;
 
32
static int res_tf0;
 
33
static int res_tf1;
 
34
static ErlDrvMutex *mtx;
 
35
static ErlDrvCond *cnd;
 
36
static int need_join[NO_OF_THREADS];
 
37
static ErlDrvTid tid[NO_OF_THREADS];
 
38
static ErlDrvThreadOpts *topts;
 
39
 
 
40
typedef struct {
 
41
    int n;
 
42
} thr_arg_t;
 
43
 
 
44
static void
 
45
do_sleep(unsigned secs)
 
46
{
 
47
#ifdef __WIN32__
 
48
        Sleep((DWORD) secs*1000);
 
49
#else
 
50
        sleep(secs);
 
51
#endif
 
52
}
 
53
 
 
54
static void *tf0(void *vta)
 
55
{
 
56
    if (((thr_arg_t *) vta)->n == 0) {
 
57
 
 
58
        erl_drv_mutex_lock(mtx);
 
59
 
 
60
        erl_drv_cond_wait(cnd, mtx);
 
61
 
 
62
        if (die) {
 
63
            erl_drv_mutex_unlock(mtx);
 
64
            return NULL;
 
65
        }
 
66
 
 
67
        cw_passed++;
 
68
 
 
69
        erl_drv_cond_wait(cnd, mtx);
 
70
 
 
71
        if (die) {
 
72
            erl_drv_mutex_unlock(mtx);
 
73
            return NULL;
 
74
        }
 
75
 
 
76
        cw_passed++;
 
77
 
 
78
        erl_drv_mutex_unlock(mtx);
 
79
        if (erl_drv_equal_tids(erl_drv_thread_self(), tid[0]))
 
80
            res_tf0 = 0;
 
81
    }
 
82
 
 
83
    return (void *) &res_tf0;
 
84
}
 
85
 
 
86
 
 
87
static void *tf1(void *vta)
 
88
{
 
89
 
 
90
    if (((thr_arg_t *) vta)->n == 1) {
 
91
 
 
92
        erl_drv_mutex_lock(mtx);
 
93
 
 
94
        erl_drv_cond_wait(cnd, mtx);
 
95
 
 
96
        if (die) {
 
97
            erl_drv_mutex_unlock(mtx);
 
98
            return NULL;
 
99
        }
 
100
 
 
101
        cw_passed++;
 
102
 
 
103
        erl_drv_cond_wait(cnd, mtx);
 
104
 
 
105
        if (die) {
 
106
            erl_drv_mutex_unlock(mtx);
 
107
            return NULL;
 
108
        }
 
109
 
 
110
        cw_passed++;
 
111
 
 
112
        erl_drv_mutex_unlock(mtx);
 
113
 
 
114
        if (erl_drv_equal_tids(erl_drv_thread_self(), tid[1]))
 
115
            res_tf1 = 1;
 
116
 
 
117
        erl_drv_thread_exit((void *) &res_tf1);
 
118
 
 
119
        res_tf1 = 4711;
 
120
    }
 
121
    return NULL;
 
122
}
 
123
 
 
124
void
 
125
testcase_run(TestCaseState_t *tcs)
 
126
{
 
127
    int i, r;
 
128
    void *tres[2];
 
129
    thr_arg_t ta[2];
 
130
    ErlDrvTid my_tid;
 
131
    ErlDrvSysInfo sinfo;
 
132
 
 
133
    driver_system_info(&sinfo, sizeof(ErlDrvSysInfo));
 
134
    if (!sinfo.thread_support)
 
135
        testcase_skipped(tcs, "No thread support; nothing to test");
 
136
 
 
137
    testcase_printf(tcs, "Initializing\n");
 
138
 
 
139
    cw_passed = 0;
 
140
    die = 0;
 
141
    my_tid = erl_drv_thread_self();
 
142
 
 
143
    for (i = 0; i < NO_OF_THREADS; i++)
 
144
        need_join[i] = 0;
 
145
 
 
146
    res_tf0 = 17;
 
147
    res_tf1 = 17;
 
148
 
 
149
    mtx = NULL;
 
150
    cnd = NULL;
 
151
    /* Create mutex and cond */
 
152
    mtx = erl_drv_mutex_create("mutex");
 
153
    ASSERT(tcs, mtx);
 
154
    cnd = erl_drv_cond_create("cond");
 
155
    ASSERT(tcs, cnd);
 
156
    topts = erl_drv_thread_opts_create("thread opts");
 
157
    ASSERT(tcs, topts);
 
158
    topts->suggested_stack_size = 0; /* As small as possible */
 
159
 
 
160
    testcase_printf(tcs, "Creating threads 0 & 1\n");
 
161
 
 
162
    /* Create the threads */
 
163
    ta[0].n = 0;
 
164
    r = erl_drv_thread_create("thread 0", &tid[0], tf0, (void *) &ta[0], topts);
 
165
    ASSERT(tcs, r == 0);
 
166
    need_join[0] = 1;
 
167
 
 
168
    ta[1].n = 1;
 
169
    r = erl_drv_thread_create("thread 1", &tid[1], tf1, (void *) &ta[1], NULL);
 
170
    ASSERT(tcs, r == 0);
 
171
    need_join[1] = 1;
 
172
 
 
173
    testcase_printf(tcs, "Testing tids\n");
 
174
 
 
175
    ASSERT(tcs, !erl_drv_equal_tids(tid[0], my_tid));
 
176
    ASSERT(tcs, !erl_drv_equal_tids(tid[1], my_tid));
 
177
    ASSERT(tcs, !erl_drv_equal_tids(tid[0], tid[1]));
 
178
    ASSERT(tcs, erl_drv_equal_tids(my_tid, erl_drv_thread_self()));
 
179
 
 
180
    testcase_printf(tcs, "Testing mutex/cond\n");
 
181
 
 
182
    /* Make sure the threads waits on cond wait */
 
183
    do_sleep(1);
 
184
 
 
185
    erl_drv_mutex_lock(mtx);
 
186
 
 
187
    ASSERT_CLNUP(tcs, cw_passed == 0, erl_drv_mutex_unlock(mtx));
 
188
 
 
189
    /* Let one thread pass one cond wait */
 
190
    erl_drv_cond_signal(cnd);
 
191
 
 
192
    erl_drv_mutex_unlock(mtx);
 
193
 
 
194
    do_sleep(1);
 
195
 
 
196
    erl_drv_mutex_lock(mtx);
 
197
 
 
198
    ASSERT_CLNUP(tcs, cw_passed == 1, erl_drv_mutex_unlock(mtx));
 
199
 
 
200
 
 
201
    /* Let both threads pass one cond wait */
 
202
    erl_drv_cond_broadcast(cnd);
 
203
 
 
204
    erl_drv_mutex_unlock(mtx);
 
205
 
 
206
    do_sleep(1);
 
207
 
 
208
    erl_drv_mutex_lock(mtx);
 
209
 
 
210
    ASSERT_CLNUP(tcs, cw_passed == 3, erl_drv_mutex_unlock(mtx));
 
211
 
 
212
 
 
213
    /* Let the thread that only have passed one cond wait pass the other one */
 
214
    erl_drv_cond_signal(cnd);
 
215
 
 
216
    erl_drv_mutex_unlock(mtx);
 
217
 
 
218
    do_sleep(1);
 
219
 
 
220
    erl_drv_mutex_lock(mtx);
 
221
 
 
222
    ASSERT_CLNUP(tcs, cw_passed == 4, erl_drv_mutex_unlock(mtx));
 
223
 
 
224
 
 
225
    testcase_printf(tcs, "Testing join\n");
 
226
 
 
227
    /* Both threads should have passed both cond waits and exited;
 
228
       join them and check returned values */
 
229
 
 
230
    erl_drv_thread_join(tid[0], &tres[0]);
 
231
    ASSERT_CLNUP(tcs, r == 0, erl_drv_mutex_unlock(mtx));
 
232
    need_join[0] = 0;
 
233
 
 
234
    ASSERT_CLNUP(tcs, tres[0] == &res_tf0, erl_drv_mutex_unlock(mtx));
 
235
    ASSERT_CLNUP(tcs, res_tf0 == 0, erl_drv_mutex_unlock(mtx));
 
236
 
 
237
    r = erl_drv_thread_join(tid[1], &tres[1]);
 
238
    ASSERT_CLNUP(tcs, r == 0, erl_drv_mutex_unlock(mtx));
 
239
    need_join[1] = 0;
 
240
 
 
241
    ASSERT_CLNUP(tcs, tres[1] == &res_tf1, erl_drv_mutex_unlock(mtx));
 
242
    ASSERT_CLNUP(tcs, res_tf1 == 1, erl_drv_mutex_unlock(mtx));
 
243
 
 
244
    /* Test signaling when noone waits */
 
245
 
 
246
    erl_drv_cond_signal(cnd);
 
247
 
 
248
    /* Test broadcasting when noone waits */
 
249
 
 
250
    erl_drv_cond_broadcast(cnd);
 
251
 
 
252
    erl_drv_mutex_unlock(mtx);
 
253
 
 
254
    erl_drv_mutex_destroy(mtx);
 
255
    mtx = NULL;
 
256
 
 
257
    erl_drv_cond_destroy(cnd);
 
258
    cnd = NULL;
 
259
 
 
260
    erl_drv_thread_opts_destroy(topts);
 
261
    topts = NULL;
 
262
 
 
263
    testcase_printf(tcs, "done\n");
 
264
}
 
265
 
 
266
char *
 
267
testcase_name(void)
 
268
{
 
269
    return "basic";
 
270
}
 
271
 
 
272
void
 
273
testcase_cleanup(TestCaseState_t *tcs)
 
274
{
 
275
    int i;
 
276
    for (i = 0; i < NO_OF_THREADS; i++) {
 
277
        if (need_join[i]) {
 
278
            erl_drv_mutex_lock(mtx);
 
279
            die = 1;
 
280
            erl_drv_cond_broadcast(cnd);
 
281
            erl_drv_mutex_unlock(mtx);
 
282
            erl_drv_thread_join(tid[i], NULL);
 
283
        }
 
284
    }
 
285
    if (mtx)
 
286
        erl_drv_mutex_destroy(mtx);
 
287
    if (cnd)
 
288
        erl_drv_cond_destroy(cnd);
 
289
    if (topts)
 
290
        erl_drv_thread_opts_destroy(topts);
 
291
}