OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [test_suite0/] [src/] [api/] [thread.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Test l4_thread_control system call.
3
 *
4
 * Copyright (C) 2010 B Labs Ltd.
5
 *
6
 * Author: Bahadir Balban
7
 */
8
 
9
#include <l4lib/lib/thread.h>
10
#include <stdio.h>
11
#include <tests.h>
12
 
13
/*
14
 * A secondary thread that tests
15
 * various conditions by taking actions
16
 * told by its parent.
17
 */
18
int new_thread_func(void *args)
19
{
20
        dbg_printf("New thread running successfully. "
21
                   "tid=%d\n", self_tid());
22
 
23
        return 0;
24
}
25
 
26
/*
27
 * Thread that exits by doing some number of
28
 * thread switches to ensure parent has a chance
29
 * to wait on it or attempt to destroy it
30
 * The purpose is to test parent-wait before self-destroy.
31
 */
32
int delayed_exit_func(void *args)
33
{
34
        int x = 5;
35
        l4id_t parent = *((l4id_t *)args);
36
 
37
        dbg_printf("%s: thread running successfully. "
38
                   "tid=%d\n", __FUNCTION__, self_tid());
39
 
40
        /*
41
         * Switch to parent a few times to ensure it
42
         * runs and begins to wait on us
43
         */
44
        while (x--)
45
                l4_thread_switch(parent);
46
 
47
        return 5;
48
}
49
 
50
/*
51
 * Thread that exits immediately
52
 * Purpose is to test parent-wait after self-destroy.
53
 */
54
int imm_exit_func(void *args)
55
{
56
        return 5;
57
}
58
 
59
/*
60
 * We have 3 thread creation scenarios to test.
61
 */
62
struct l4_thread *test_thread_create()
63
{
64
        struct l4_thread *tptr;
65
        int err;
66
 
67
        dbg_printf("%s: Creating thread", __FUNCTION__);
68
 
69
        /*
70
         * Create a thread in the same space
71
         */
72
        if ((err = thread_create(new_thread_func, 0,
73
                                 TC_SHARE_SPACE,
74
                                 &tptr)) < 0) {
75
                dbg_printf("Thread create failed. "
76
                           "err=%d\n", err);
77
                return PTR_ERR(err);
78
        }
79
 
80
        dbg_printf("Thread created successfully. "
81
                   "tid=%d\n", tptr->ids.tid);
82
 
83
        return tptr;
84
}
85
 
86
/*
87
 * Test thread run/resume, suspend
88
 *
89
 * We don't test recycle as that would delete the current
90
 * address space
91
 */
92
int test_thread_actions(struct l4_thread *thread)
93
{
94
        int err;
95
 
96
        dbg_printf("Suspending thread "
97
                   "tid=%d\n", thread->ids.tid);
98
 
99
        /*
100
         * Suspend/resume the thread
101
         */
102
        if ((err = l4_thread_control(THREAD_SUSPEND, &thread->ids)) < 0) {
103
                dbg_printf("THREAD_SUSPEND failed. "
104
                           "err=%d\n", err);
105
                return err;
106
        }
107
 
108
        dbg_printf("Suspend OK. Resuming thread "
109
                   "tid=%d\n", thread->ids.tid);
110
 
111
        if ((err = l4_thread_control(THREAD_RUN, &thread->ids)) < 0) {
112
                dbg_printf("THREAD_RUN failed. "
113
                           "err=%d\n", err);
114
                return err;
115
        }
116
 
117
        dbg_printf("Resume OK."
118
                   "tid=%d\n", thread->ids.tid);
119
 
120
        return 0;
121
}
122
 
123
/*
124
 * Test thread destruction
125
 */
126
int test_thread_destroy(struct l4_thread *thread)
127
{
128
        int err;
129
        l4id_t id_self = self_tid();
130
 
131
        dbg_printf("Destroying thread."
132
                   "tid=%d\n", thread->ids.tid);
133
 
134
        /*
135
         * Destroy the thread from parent
136
         */
137
        if ((err = thread_destroy(thread)) < 0) {
138
                dbg_printf("THREAD_DESTROY failed. "
139
                           "err=%d\n", err);
140
                return err;
141
        }
142
 
143
        dbg_printf("%s: Destroy OK\n", __FUNCTION__);
144
 
145
        dbg_printf("%s: Creating new thread\n", __FUNCTION__);
146
 
147
        /*
148
         * Create a new thread
149
         * and tell it to destroy itself
150
         * by adding a delay, then wait on it.
151
         *
152
         * Delay ensures we test the case that
153
         * wait occurs before thread is destroyed.
154
         */
155
        if ((err = thread_create(delayed_exit_func, &id_self,
156
                                 TC_SHARE_SPACE,
157
                                 &thread)) < 0) {
158
                dbg_printf("THREAD_CREATE failed. "
159
                           "err=%d\n", err);
160
                return err;
161
        }
162
 
163
        dbg_printf("Thread created successfully. "
164
                   "tid=%d\n", thread->ids.tid);
165
 
166
        dbg_printf("Waiting on thread, "
167
                   "tid=%d\n", thread->ids.tid);
168
 
169
        /* Wait on the thread */
170
        if ((err = thread_wait(thread)) < 0) {
171
                dbg_printf("THREAD_WAIT failed. "
172
                           "err=%d\n", err);
173
                return err;
174
        } else {
175
                dbg_printf("Thread %d exited successfully. ret=%d\n",
176
                           thread->ids.tid, err);
177
        }
178
 
179
        /*
180
         * Create a new thread
181
         * and tell it to destroy itself
182
         * immediately, add a delay and
183
         * then wait on it.
184
         *
185
         * Delay ensures we test the case that
186
         * wait occurs after thread is destroyed.
187
         */
188
        if ((err = thread_create(imm_exit_func, 0,
189
                                 TC_SHARE_SPACE,
190
                                 &thread)) < 0) {
191
                dbg_printf("THREAD_WAIT failed. "
192
                           "err=%d\n", err);
193
                return err;
194
        }
195
 
196
        /* Wait on the thread */
197
        if ((err = thread_wait(thread)) < 0) {
198
                dbg_printf("THREAD_WAIT failed. "
199
                           "err=%d\n", err);
200
                return err;
201
        } else {
202
                dbg_printf("Thread %d exited successfully. ret=%d\n",
203
                           thread->ids.tid, err);
204
        }
205
 
206
        return 0;
207
}
208
 
209
/*
210
 * TODO: In order to test null pointers a separate
211
 * thread who is paged by the main one should attempt
212
 * to pass a null ptr.
213
 */
214
int test_thread_invalid(struct l4_thread *thread)
215
{
216
        return 0;
217
}
218
 
219
int test_api_tctrl(void)
220
{
221
        struct l4_thread *thread;
222
        int err;
223
 
224
        /* Test thread create */
225
        if (IS_ERR(thread = test_thread_create())) {
226
                err = (int)thread;
227
                goto out_err;
228
        }
229
 
230
        /* Test thread actions */
231
        if ((err = test_thread_actions(thread)) < 0)
232
                goto out_err;
233
 
234
        /* Test thread destruction */
235
        if ((err = test_thread_destroy(thread)) < 0)
236
                goto out_err;
237
 
238
        /* Test thread invalid input */
239
        if ((err = test_thread_invalid(thread)) < 0)
240
                goto out_err;
241
 
242
        printf("THREAD CONTROL:                -- PASSED --\n");
243
        return 0;
244
 
245
out_err:
246
        printf("THREAD CONTROL:                -- FAILED --\n");
247
        return err;
248
}
249
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.