Statistics
| Branch: | Revision:

root / prex-0.9.0 / usr / sample / mutex / mutex.c @ 03e9c04a

History | View | Annotate | Download (5.59 KB)

1
/*
2
 * Copyright (c) 2005, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * mutex.c - sample program for mutex with priority inheritance.
32
 */
33

    
34
/*
35
 * Senario:
36
 * This sample shows how the mutex priority is changed when three
37
 * different threads lock two mutexes at same time.
38
 *
39
 * The priority of each thread are as follows.
40
 *    Thread1 - priority 100 (highest)
41
 *    Thread2 - priority 101
42
 *    Thread3 - priority 102
43
 *
44
 * Thread priority and state are changed as follows.
45
 *
46
 *    Action                    Thread 1  Thread 2  Thread 3  Mutex A  Mutex B
47
 *    ------------------------  --------  --------  --------  -------  -------
48
 * 1) Thread 3 locks mutex A    susp/100  susp/101  run /102  owner=3
49
 * 2) Thread 2 locks mutex B    susp/100  run /101  run /102  owner=3  owner=2
50
 * 3) Thread 2 locks mutex A    susp/100  wait/101  run /101* owner=3  owner=2
51
 * 4) Thread 1 locks mutex B    wait/100  wait/100* run /100* owner=3  owner=2
52
 * 5) Thread 3 unlocks mutex A  wait/100  run /100  run /102* owner=2* owner=2
53
 * 6) Thread 2 unlocks mutex B  run /100* run /100  run /102  owner=2  owner=1*
54
 * 7) Thread 2 unlocks mutex A  run /100  run /100  run /102           owner=1
55
 * 8) Thread 1 unlocks mutex B  wait/100  run /101  run /102
56
 *
57
 */
58

    
59
#include <sys/prex.h>
60
#include <stdio.h>
61

    
62
static char stack[3][1024];
63
static thread_t th_1, th_2, th_3;
64
static mutex_t mtx_A, mtx_B;
65

    
66
static void
67
dump_pri(void)
68
{
69
        int pri;
70

    
71
        if (thread_getpri(th_1, &pri) == 0)
72
                printf("th_1: pri=%d\n", pri);
73

    
74
        if (thread_getpri(th_2, &pri) == 0)
75
                printf("th_2: pri=%d\n", pri);
76

    
77
        if (thread_getpri(th_3, &pri) == 0)
78
                printf("th_3: pri=%d\n", pri);
79
}
80

    
81
thread_t
82
thread_run(void (*start)(void), void *stack)
83
{
84
        thread_t t;
85

    
86
        if (thread_create(task_self(), &t) != 0)
87
                panic("thread_create is failed");
88

    
89
        if (thread_load(t, start, stack) != 0)
90
                panic("thread_load is failed");
91

    
92
        return t;
93
}
94

    
95
/*
96
 * Thread 1 - Priority = 100
97
 */
98
static void
99
thread_1(void)
100
{
101
        printf("thread_1: starting\n");
102

    
103
        /*
104
         * 4) Lock mutex B
105
         *
106
         * Priority inheritance:
107
         *    Thread 2... Pri 101 -> 100
108
         *    Thread 3... Pri 101 -> 100
109
         */
110
        printf("thread_1: 4) lock B\n");
111
        mutex_lock(&mtx_B);
112

    
113
        printf("thread_1: running\n");
114
        dump_pri();
115

    
116
        /*
117
         * 8) Unlock mutex B
118
         */
119
        printf("thread_1: 7) unlock B\n");
120
        mutex_unlock(&mtx_B);
121

    
122
        dump_pri();
123
        printf("thread_1: exit\n");
124
        thread_terminate(th_1);
125
}
126

    
127
/*
128
 * Thread 2 - Priority = 101
129
 */
130
static void
131
thread_2(void)
132
{
133
        printf("thread_2: starting\n");
134

    
135
        /*
136
         * 2) Lock mutex B
137
         */
138
        printf("thread_2: 2) lock B\n");
139
        mutex_lock(&mtx_B);
140
        dump_pri();
141

    
142
        /*
143
         * 3) Lock mutex A (Switch to thread 3)
144
         *
145
         * Priority inheritance:
146
         *    Thread 3... Pri 102 -> 101
147
         */
148
        printf("thread_2: 3) lock A\n");
149
        mutex_lock(&mtx_A);
150

    
151
        printf("thread_2: running\n");
152
        dump_pri();
153

    
154
        /*
155
         * 6) Unlock mutex B
156
         */
157
        printf("thread_2: 6) unlock B\n");
158
        mutex_unlock(&mtx_B);
159

    
160
        dump_pri();
161

    
162
        /*
163
         * 7) Unlock mutex A
164
         */
165
        printf("thread_2: 8) unlock A\n");
166
        mutex_unlock(&mtx_A);
167

    
168
        printf("thread_2: exit\n");
169
        thread_terminate(th_2);
170
}
171

    
172

    
173
/*
174
 * Thread 3 - Priority = 102
175
 */
176
static void
177
thread_3(void)
178
{
179
        printf("thread_3: start\n");
180

    
181
        /*
182
         * 1) Lock mutex A
183
         */
184
        printf("thread_3: 1) lock A\n");
185
        mutex_lock(&mtx_A);
186
        dump_pri();
187

    
188
        /*
189
         * Start thread 2
190
         */
191
        thread_resume(th_2);
192

    
193
        /*
194
         * Check priority
195
         */
196
        printf("thread_3: running-1\n");
197
        dump_pri();
198

    
199
        /*
200
         * Start thread 1
201
         */
202
        thread_resume(th_1);
203
        printf("thread_3: running-2\n");
204
        dump_pri();
205

    
206
        /*
207
         * 5) Unlock mutex A
208
         */
209
        printf("thread_3: 5) unlock A\n");
210
        mutex_unlock(&mtx_A);
211

    
212
        dump_pri();
213
        printf("thread_3: exit\n");
214
        thread_terminate(th_3);
215
}
216

    
217
int
218
main(int argc, char *argv[])
219
{
220
        printf("Mutex sample program\n");
221

    
222
        /*
223
         * Boost priority of this thread
224
         */
225
        thread_setpri(thread_self(), 90);
226

    
227
        /*
228
         * Initialize mutexes.
229
         */
230
        mutex_init(&mtx_A);
231
        mutex_init(&mtx_B);
232

    
233
        /*
234
         * Create new threads
235
         */
236
        th_1 = thread_run(thread_1, stack[0]+1024);
237
        thread_setpri(th_1, 100);
238

    
239
        th_2 = thread_run(thread_2, stack[1]+1024);
240
        thread_setpri(th_2, 101);
241

    
242
        th_3 = thread_run(thread_3, stack[2]+1024);
243
        thread_setpri(th_3, 102);
244

    
245
        dump_pri();
246

    
247
        /*
248
         * Start lowest priority thread
249
         */
250
        thread_resume(th_3);
251

    
252
        /*
253
         * Wait...
254
         */
255
        thread_suspend(thread_self());
256

    
257
        return 0;
258
}