Annotation of prex/usr/sample/mutex/mutex.c, Revision 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