Annotation of prex/usr/sample/mutex/mutex.c, Revision 1.1.1.1
1.1 nbrk 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 inheritence.
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 follow.
40: * Thread1 - priority 100 (highest)
41: * Thread2 - priority 101
42: * Thread3 - priority 102
43: *
44: * Thread priority and state are changed as follow.
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 <prex/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_prio(void)
68: {
69: int prio;
70:
71: if (thread_getprio(th_1, &prio) == 0)
72: printf("th_1: prio=%d\n", prio);
73:
74: if (thread_getprio(th_2, &prio) == 0)
75: printf("th_2: prio=%d\n", prio);
76:
77: if (thread_getprio(th_3, &prio) == 0)
78: printf("th_3: prio=%d\n", prio);
79: }
80:
81: thread_t
82: thread_run(void (*start)(void), void *stack)
83: {
84: thread_t th;
85:
86: if (thread_create(task_self(), &th) != 0)
87: panic("thread_create is failed");
88:
89: if (thread_load(th, start, stack) != 0)
90: panic("thread_load is failed");
91:
92: return th;
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... Prio 101 -> 100
108: * Thread 3... Prio 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_prio();
115:
116: /*
117: * 8) Unlock mutex B
118: */
119: printf("thread_1: 7) unlock B\n");
120: mutex_unlock(&mtx_B);
121:
122: dump_prio();
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_prio();
141:
142: /*
143: * 3) Lock mutex A (Switch to thread 3)
144: *
145: * Priority inheritance:
146: * Thread 3... Prio 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_prio();
153:
154: /*
155: * 6) Unlock mutex B
156: */
157: printf("thread_2: 6) unlock B\n");
158: mutex_unlock(&mtx_B);
159:
160: dump_prio();
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_prio();
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_prio();
198:
199: /*
200: * Start thread 1
201: */
202: thread_resume(th_1);
203: printf("thread_3: running-2\n");
204: dump_prio();
205:
206: /*
207: * 5) Unlock mutex A
208: */
209: printf("thread_3: 5) unlock A\n");
210: mutex_unlock(&mtx_A);
211:
212: dump_prio();
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_setprio(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_setprio(th_1, 100);
238:
239: th_2 = thread_run(thread_2, stack[1]+1024);
240: thread_setprio(th_2, 101);
241:
242: th_3 = thread_run(thread_3, stack[2]+1024);
243: thread_setprio(th_3, 102);
244:
245: dump_prio();
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: }
CVSweb