0000: 23 69 6e 63 6c 75 64 65 20 22 73 79 6e 63 2e 68 #include "sync.h
0010: 22 0a 0a 0a 23 69 66 20 49 4e 54 45 52 46 41 43 "...#if INTERFAC
0020: 45 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 E.#include <stdi
0030: 6e 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c nt.h>.#include <
0040: 73 74 64 64 65 66 2e 68 3e 0a 0a 74 79 70 65 64 stddef.h>..typed
0050: 65 66 20 76 6f 6c 61 74 69 6c 65 20 75 69 6e 74 ef volatile uint
0060: 33 32 5f 74 20 73 70 69 6e 5f 74 3b 0a 0a 73 74 32_t spin_t;..st
0070: 72 75 63 74 20 6d 6f 6e 69 74 6f 72 5f 74 20 7b ruct monitor_t {
0080: 0a 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 ..interrupt_moni
0090: 74 6f 72 5f 74 20 6c 6f 63 6b 5b 31 5d 3b 0a 09 tor_t lock[1];..
00a0: 74 68 72 65 61 64 5f 74 20 2a 20 76 6f 6c 61 74 thread_t * volat
00b0: 69 6c 65 20 6f 77 6e 65 72 3b 0a 09 76 6f 6c 61 ile owner;..vola
00c0: 74 69 6c 65 20 69 6e 74 20 63 6f 75 6e 74 3b 0a tile int count;.
00d0: 7d 3b 0a 0a 73 74 72 75 63 74 20 72 77 6c 6f 63 };..struct rwloc
00e0: 6b 5f 74 20 7b 0a 09 6d 6f 6e 69 74 6f 72 5f 74 k_t {..monitor_t
00f0: 20 6c 6f 63 6b 5b 31 5d 3b 0a 09 69 6e 74 20 72 lock[1];..int r
0100: 65 61 64 63 6f 75 6e 74 3b 0a 09 74 68 72 65 61 eadcount;..threa
0110: 64 5f 74 20 2a 20 76 6f 6c 61 74 69 6c 65 20 77 d_t * volatile w
0120: 72 69 74 65 72 3b 0a 7d 3b 0a 0a 73 74 72 75 63 riter;.};..struc
0130: 74 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 t interrupt_moni
0140: 74 6f 72 5f 74 20 7b 0a 09 73 70 69 6e 5f 74 20 tor_t {..spin_t
0150: 73 70 69 6e 3b 0a 09 74 68 72 65 61 64 5f 74 20 spin;..thread_t
0160: 2a 20 76 6f 6c 61 74 69 6c 65 20 6f 77 6e 65 72 * volatile owner
0170: 3b 0a 09 74 68 72 65 61 64 5f 74 20 2a 20 76 6f ;..thread_t * vo
0180: 6c 61 74 69 6c 65 20 77 61 69 74 69 6e 67 3b 0a latile waiting;.
0190: 09 74 69 6d 65 72 5f 65 76 65 6e 74 5f 74 20 74 .timer_event_t t
01a0: 69 6d 65 72 5b 31 5d 3b 0a 7d 3b 0a 0a 23 64 65 imer[1];.};..#de
01b0: 66 69 6e 65 20 49 4e 49 54 5f 4f 4e 43 45 28 29 fine INIT_ONCE()
01c0: 20 5c 0a 09 64 6f 20 7b 20 5c 0a 09 09 73 74 61 \..do { \...sta
01d0: 74 69 63 20 69 6e 74 20 69 6e 69 74 65 64 20 3d tic int inited =
01e0: 20 30 3b 20 5c 0a 09 09 69 66 20 28 69 6e 69 74 0; \...if (init
01f0: 65 64 29 20 7b 20 5c 0a 09 09 09 72 65 74 75 72 ed) { \....retur
0200: 6e 3b 20 5c 0a 09 09 7d 20 5c 0a 09 09 69 6e 69 n; \...} \...ini
0210: 74 65 64 20 3d 20 31 3b 20 5c 0a 09 7d 20 77 68 ted = 1; \..} wh
0220: 69 6c 65 28 30 29 0a 0a 74 79 70 65 64 65 66 20 ile(0)..typedef
0230: 6d 6f 6e 69 74 6f 72 5f 74 20 6d 75 74 65 78 5f monitor_t mutex_
0240: 74 3b 0a 0a 23 64 65 66 69 6e 65 20 41 55 54 4f t;..#define AUTO
0250: 4c 4f 43 4b 5f 43 4f 4e 43 41 54 28 61 2c 20 62 LOCK_CONCAT(a, b
0260: 29 20 61 20 23 23 20 62 0a 23 64 65 66 69 6e 65 ) a ## b.#define
0270: 20 41 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 6c 69 AUTOLOCK_VAR(li
0280: 6e 65 29 20 41 55 54 4f 4c 4f 43 4b 5f 43 4f 4e ne) AUTOLOCK_CON
0290: 43 41 54 28 73 2c 6c 69 6e 65 29 0a 23 64 65 66 CAT(s,line).#def
02a0: 69 6e 65 20 53 50 49 4e 5f 41 55 54 4f 4c 4f 43 ine SPIN_AUTOLOC
02b0: 4b 28 6c 6f 63 6b 29 20 73 70 69 6e 5f 74 20 41 K(lock) spin_t A
02c0: 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 UTOLOCK_VAR(__LI
02d0: 4e 45 5f 5f 29 20 3d 20 30 3b 20 77 68 69 6c 65 NE__) = 0; while
02e0: 28 28 41 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f ((AUTOLOCK_VAR(_
02f0: 5f 4c 49 4e 45 5f 5f 29 20 3d 73 70 69 6e 5f 61 _LINE__) =spin_a
0300: 75 74 6f 6c 6f 63 6b 28 6c 6f 63 6b 2c 20 41 55 utolock(lock, AU
0310: 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e TOLOCK_VAR(__LIN
0320: 45 5f 5f 29 20 29 29 29 0a 23 69 66 20 30 0a 23 E__) ))).#if 0.#
0330: 64 65 66 69 6e 65 20 4d 55 54 45 58 5f 41 55 54 define MUTEX_AUT
0340: 4f 4c 4f 43 4b 28 6c 6f 63 6b 29 20 69 6e 74 20 OLOCK(lock) int
0350: 41 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c AUTOLOCK_VAR(__L
0360: 49 4e 45 5f 5f 29 20 3d 20 30 3b 20 77 68 69 6c INE__) = 0; whil
0370: 65 28 28 41 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 e((AUTOLOCK_VAR(
0380: 5f 5f 4c 49 4e 45 5f 5f 29 20 3d 6d 75 74 65 78 __LINE__) =mutex
0390: 5f 61 75 74 6f 6c 6f 63 6b 28 6c 6f 63 6b 2c 20 _autolock(lock,
03a0: 41 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c AUTOLOCK_VAR(__L
03b0: 49 4e 45 5f 5f 29 20 29 29 29 0a 23 65 6e 64 69 INE__) ))).#endi
03c0: 66 0a 23 64 65 66 69 6e 65 20 4d 55 54 45 58 5f f.#define MUTEX_
03d0: 41 55 54 4f 4c 4f 43 4b 28 6c 6f 63 6b 29 20 4d AUTOLOCK(lock) M
03e0: 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 ONITOR_AUTOLOCK(
03f0: 6c 6f 63 6b 29 0a 23 64 65 66 69 6e 65 20 4d 4f lock).#define MO
0400: 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 6c NITOR_AUTOLOCK(l
0410: 6f 63 6b 29 20 69 6e 74 20 41 55 54 4f 4c 4f 43 ock) int AUTOLOC
0420: 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 5f 5f 29 20 K_VAR(__LINE__)
0430: 3d 20 30 3b 20 77 68 69 6c 65 28 28 41 55 54 4f = 0; while((AUTO
0440: 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 5f LOCK_VAR(__LINE_
0450: 5f 29 20 3d 6d 6f 6e 69 74 6f 72 5f 61 75 74 6f _) =monitor_auto
0460: 6c 6f 63 6b 28 6c 6f 63 6b 2c 20 41 55 54 4f 4c lock(lock, AUTOL
0470: 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 5f 5f OCK_VAR(__LINE__
0480: 29 20 29 29 29 0a 23 64 65 66 69 6e 65 20 49 4e ) ))).#define IN
0490: 54 45 52 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f TERRUPT_MONITOR_
04a0: 41 55 54 4f 4c 4f 43 4b 28 6c 6f 63 6b 29 20 69 AUTOLOCK(lock) i
04b0: 6e 74 20 41 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 nt AUTOLOCK_VAR(
04c0: 5f 5f 4c 49 4e 45 5f 5f 29 20 3d 20 30 3b 20 77 __LINE__) = 0; w
04d0: 68 69 6c 65 28 28 41 55 54 4f 4c 4f 43 4b 5f 56 hile((AUTOLOCK_V
04e0: 41 52 28 5f 5f 4c 49 4e 45 5f 5f 29 20 3d 69 6e AR(__LINE__) =in
04f0: 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f terrupt_monitor_
0500: 61 75 74 6f 6c 6f 63 6b 28 6c 6f 63 6b 2c 20 41 autolock(lock, A
0510: 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 UTOLOCK_VAR(__LI
0520: 4e 45 5f 5f 29 20 29 29 29 0a 23 64 65 66 69 6e NE__) ))).#defin
0530: 65 20 52 45 41 44 45 52 5f 41 55 54 4f 4c 4f 43 e READER_AUTOLOC
0540: 4b 28 6c 6f 63 6b 29 20 69 6e 74 20 41 55 54 4f K(lock) int AUTO
0550: 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 5f LOCK_VAR(__LINE_
0560: 5f 29 20 3d 20 30 3b 20 77 68 69 6c 65 28 28 41 _) = 0; while((A
0570: 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 UTOLOCK_VAR(__LI
0580: 4e 45 5f 5f 29 20 3d 72 77 6c 6f 63 6b 5f 61 75 NE__) =rwlock_au
0590: 74 6f 6c 6f 63 6b 28 6c 6f 63 6b 2c 20 41 55 54 tolock(lock, AUT
05a0: 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 OLOCK_VAR(__LINE
05b0: 5f 5f 29 2c 20 30 29 29 29 0a 23 64 65 66 69 6e __), 0))).#defin
05c0: 65 20 57 52 49 54 45 52 5f 41 55 54 4f 4c 4f 43 e WRITER_AUTOLOC
05d0: 4b 28 6c 6f 63 6b 29 20 69 6e 74 20 41 55 54 4f K(lock) int AUTO
05e0: 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 5f LOCK_VAR(__LINE_
05f0: 5f 29 20 3d 20 30 3b 20 77 68 69 6c 65 28 28 41 _) = 0; while((A
0600: 55 54 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 UTOLOCK_VAR(__LI
0610: 4e 45 5f 5f 29 20 3d 72 77 6c 6f 63 6b 5f 61 75 NE__) =rwlock_au
0620: 74 6f 6c 6f 63 6b 28 6c 6f 63 6b 2c 20 41 55 54 tolock(lock, AUT
0630: 4f 4c 4f 43 4b 5f 56 41 52 28 5f 5f 4c 49 4e 45 OLOCK_VAR(__LINE
0640: 5f 5f 29 2c 20 31 29 29 29 0a 0a 23 65 6e 64 69 __), 1)))..#endi
0650: 66 0a 0a 65 78 63 65 70 74 69 6f 6e 5f 64 65 66 f..exception_def
0660: 20 54 69 6d 65 6f 75 74 45 78 63 65 70 74 69 6f TimeoutExceptio
0670: 6e 20 3d 20 7b 20 22 54 69 6d 65 6f 75 74 45 78 n = { "TimeoutEx
0680: 63 65 70 74 69 6f 6e 22 2c 20 26 45 78 63 65 70 ception", &Excep
0690: 74 69 6f 6e 20 7d 3b 0a 0a 23 69 66 20 30 0a 73 tion };..#if 0.s
06a0: 74 61 74 69 63 20 76 6f 69 64 20 6d 75 74 65 78 tatic void mutex
06b0: 5f 6d 61 72 6b 28 76 6f 69 64 20 2a 20 70 29 0a _mark(void * p).
06c0: 7b 0a 09 6d 75 74 65 78 5f 74 20 2a 20 6c 6f 63 {..mutex_t * loc
06d0: 6b 20 3d 20 70 3b 0a 0a 09 73 6c 61 62 5f 67 63 k = p;...slab_gc
06e0: 5f 6d 61 72 6b 28 6c 6f 63 6b 2d 3e 6f 77 6e 65 _mark(lock->owne
06f0: 72 29 3b 0a 09 73 6c 61 62 5f 67 63 5f 6d 61 72 r);..slab_gc_mar
0700: 6b 28 6c 6f 63 6b 2d 3e 77 61 69 74 69 6e 67 29 k(lock->waiting)
0710: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 73 6c 61 62 ;.}..static slab
0720: 5f 74 79 70 65 5f 74 20 6d 75 74 65 78 65 73 5b _type_t mutexes[
0730: 31 5d 20 3d 20 7b 53 4c 41 42 5f 54 59 50 45 28 1] = {SLAB_TYPE(
0740: 73 69 7a 65 6f 66 28 6d 75 74 65 78 5f 74 29 2c sizeof(mutex_t),
0750: 20 6d 75 74 65 78 5f 6d 61 72 6b 2c 20 30 29 7d mutex_mark, 0)}
0760: 3b 0a 23 65 6e 64 69 66 0a 0a 23 69 66 20 30 0a ;.#endif..#if 0.
0770: 73 74 61 74 69 63 20 76 6f 69 64 20 6d 6f 6e 69 static void moni
0780: 74 6f 72 5f 6d 61 72 6b 28 76 6f 69 64 20 2a 20 tor_mark(void *
0790: 70 29 0a 7b 0a 09 6d 6f 6e 69 74 6f 72 5f 74 20 p).{..monitor_t
07a0: 2a 20 6c 6f 63 6b 20 3d 20 70 3b 0a 0a 09 73 6c * lock = p;...sl
07b0: 61 62 5f 67 63 5f 6d 61 72 6b 28 6c 6f 63 6b 2d ab_gc_mark(lock-
07c0: 3e 6c 6f 63 6b 2d 3e 77 61 69 74 69 6e 67 29 3b >lock->waiting);
07d0: 0a 09 73 6c 61 62 5f 67 63 5f 6d 61 72 6b 28 6c ..slab_gc_mark(l
07e0: 6f 63 6b 2d 3e 6f 77 6e 65 72 29 3b 0a 7d 0a 23 ock->owner);.}.#
07f0: 65 6e 64 69 66 0a 0a 73 74 61 74 69 63 20 73 6c endif..static sl
0800: 61 62 5f 74 79 70 65 5f 74 20 6d 6f 6e 69 74 6f ab_type_t monito
0810: 72 73 5b 31 5d 20 3d 20 7b 53 4c 41 42 5f 54 59 rs[1] = {SLAB_TY
0820: 50 45 28 73 69 7a 65 6f 66 28 6d 6f 6e 69 74 6f PE(sizeof(monito
0830: 72 5f 74 29 2c 20 30 2c 20 30 29 7d 3b 0a 73 74 r_t), 0, 0)};.st
0840: 61 74 69 63 20 47 43 52 4f 4f 54 20 6d 61 70 5f atic GCROOT map_
0850: 74 20 2a 20 6c 6f 63 6b 74 61 62 6c 65 3b 0a 73 t * locktable;.s
0860: 74 61 74 69 63 20 6d 75 74 65 78 5f 74 20 6c 6f tatic mutex_t lo
0870: 63 6b 74 61 62 6c 65 6c 6f 63 6b 3b 0a 0a 73 74 cktablelock;..st
0880: 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e 64 atic int contend
0890: 65 64 3b 0a 0a 69 6e 74 20 73 70 69 6e 5f 74 72 ed;..int spin_tr
08a0: 79 6c 6f 63 6b 28 73 70 69 6e 5f 74 20 2a 20 6c ylock(spin_t * l
08b0: 29 0a 7b 0a 09 72 65 74 75 72 6e 20 61 72 63 68 ).{..return arch
08c0: 5f 73 70 69 6e 5f 74 72 79 6c 6f 63 6b 28 6c 29 _spin_trylock(l)
08d0: 3b 0a 7d 0a 0a 76 6f 69 64 20 73 70 69 6e 5f 75 ;.}..void spin_u
08e0: 6e 6c 6f 63 6b 28 73 70 69 6e 5f 74 20 2a 20 6c nlock(spin_t * l
08f0: 29 0a 7b 0a 09 61 72 63 68 5f 73 70 69 6e 5f 75 ).{..arch_spin_u
0900: 6e 6c 6f 63 6b 28 6c 29 3b 0a 7d 0a 0a 76 6f 69 nlock(l);.}..voi
0910: 64 20 73 70 69 6e 5f 6c 6f 63 6b 28 73 70 69 6e d spin_lock(spin
0920: 5f 74 20 2a 20 6c 29 0a 7b 0a 09 61 72 63 68 5f _t * l).{..arch_
0930: 73 70 69 6e 5f 6c 6f 63 6b 28 6c 29 3b 0a 7d 0a spin_lock(l);.}.
0940: 0a 23 69 66 20 30 0a 69 6e 74 20 6d 75 74 65 78 .#if 0.int mutex
0950: 5f 61 75 74 6f 6c 6f 63 6b 28 6d 75 74 65 78 5f _autolock(mutex_
0960: 74 20 2a 20 6c 6f 63 6b 2c 20 69 6e 74 20 73 74 t * lock, int st
0970: 61 74 65 29 0a 7b 0a 20 20 20 20 20 20 20 20 69 ate).{. i
0980: 66 20 28 73 74 61 74 65 29 20 7b 0a 20 20 20 20 f (state) {.
0990: 20 20 20 20 20 20 20 20 20 20 20 20 6d 75 74 65 mute
09a0: 78 5f 75 6e 6c 6f 63 6b 28 6c 6f 63 6b 29 3b 0a x_unlock(lock);.
09b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
09c0: 73 74 61 74 65 20 3d 20 30 3b 0a 20 20 20 20 20 state = 0;.
09d0: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 } else {.
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 6d 75 74 65 mute
09f0: 78 5f 6c 6f 63 6b 28 6c 6f 63 6b 29 3b 0a 20 20 x_lock(lock);.
0a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 74 st
0a10: 61 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 ate = 1;.
0a20: 20 7d 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 }.. retu
0a30: 72 6e 20 73 74 61 74 65 3b 0a 7d 20 0a 23 65 6e rn state;.} .#en
0a40: 64 69 66 0a 0a 69 6e 74 20 73 70 69 6e 5f 61 75 dif..int spin_au
0a50: 74 6f 6c 6f 63 6b 28 73 70 69 6e 5f 74 20 2a 20 tolock(spin_t *
0a60: 6c 6f 63 6b 2c 20 69 6e 74 20 73 74 61 74 65 29 lock, int state)
0a70: 0a 7b 0a 20 20 20 20 20 20 20 20 69 66 20 28 73 .{. if (s
0a80: 74 61 74 65 29 20 7b 0a 20 20 20 20 20 20 20 20 tate) {.
0a90: 20 20 20 20 20 20 20 20 73 70 69 6e 5f 75 6e 6c spin_unl
0aa0: 6f 63 6b 28 6c 6f 63 6b 29 3b 0a 20 20 20 20 20 ock(lock);.
0ab0: 20 20 20 20 20 20 20 20 20 20 20 73 74 61 74 65 state
0ac0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 20 = 0;. }
0ad0: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20 else {.
0ae0: 20 20 20 20 20 20 20 73 70 69 6e 5f 6c 6f 63 6b spin_lock
0af0: 28 6c 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20 20 (lock);.
0b00: 20 20 20 20 20 20 20 20 73 74 61 74 65 20 3d 20 state =
0b10: 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 1;. }..
0b20: 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 74 61 return sta
0b30: 74 65 3b 0a 7d 20 0a 0a 69 6e 74 20 6d 6f 6e 69 te;.} ..int moni
0b40: 74 6f 72 5f 61 75 74 6f 6c 6f 63 6b 28 6d 6f 6e tor_autolock(mon
0b50: 69 74 6f 72 5f 74 20 2a 20 6c 6f 63 6b 2c 20 69 itor_t * lock, i
0b60: 6e 74 20 73 74 61 74 65 29 0a 7b 0a 20 20 20 20 nt state).{.
0b70: 20 20 20 20 69 66 20 28 73 74 61 74 65 29 20 7b if (state) {
0b80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
0b90: 20 6d 6f 6e 69 74 6f 72 5f 6c 65 61 76 65 28 6c monitor_leave(l
0ba0: 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20 20 20 20 ock);.
0bb0: 20 20 20 20 20 20 73 74 61 74 65 20 3d 20 30 3b state = 0;
0bc0: 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 . } else
0bd0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 {.
0be0: 20 20 6d 6f 6e 69 74 6f 72 5f 65 6e 74 65 72 28 monitor_enter(
0bf0: 6c 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20 20 20 lock);.
0c00: 20 20 20 20 20 20 20 73 74 61 74 65 20 3d 20 31 state = 1
0c10: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 ;. }..
0c20: 20 20 20 20 20 72 65 74 75 72 6e 20 73 74 61 74 return stat
0c30: 65 3b 0a 7d 20 0a 0a 69 6e 74 20 69 6e 74 65 72 e;.} ..int inter
0c40: 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 61 75 74 rupt_monitor_aut
0c50: 6f 6c 6f 63 6b 28 69 6e 74 65 72 72 75 70 74 5f olock(interrupt_
0c60: 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6c 6f 63 6b monitor_t * lock
0c70: 2c 20 69 6e 74 20 73 74 61 74 65 29 0a 7b 0a 20 , int state).{.
0c80: 20 20 20 20 20 20 20 69 66 20 28 73 74 61 74 65 if (state
0c90: 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 ) {.
0ca0: 20 20 20 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f interrupt_mo
0cb0: 6e 69 74 6f 72 5f 6c 65 61 76 65 28 6c 6f 63 6b nitor_leave(lock
0cc0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 );.
0cd0: 20 20 20 73 74 61 74 65 20 3d 20 30 3b 0a 20 20 state = 0;.
0ce0: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 } else {.
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 i
0d00: 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 nterrupt_monitor
0d10: 5f 65 6e 74 65 72 28 6c 6f 63 6b 29 3b 0a 20 20 _enter(lock);.
0d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 74 st
0d30: 61 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 ate = 1;.
0d40: 20 7d 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 }.. retu
0d50: 72 6e 20 73 74 61 74 65 3b 0a 7d 20 0a 0a 69 6e rn state;.} ..in
0d60: 74 20 72 77 6c 6f 63 6b 5f 61 75 74 6f 6c 6f 63 t rwlock_autoloc
0d70: 6b 28 72 77 6c 6f 63 6b 5f 74 20 2a 20 6c 6f 63 k(rwlock_t * loc
0d80: 6b 2c 20 69 6e 74 20 73 74 61 74 65 2c 20 69 6e k, int state, in
0d90: 74 20 77 72 69 74 65 29 0a 7b 0a 20 20 20 20 20 t write).{.
0da0: 20 20 20 69 66 20 28 73 74 61 74 65 29 20 7b 0a if (state) {.
0db0: 09 09 72 77 6c 6f 63 6b 5f 75 6e 6c 6f 63 6b 28 ..rwlock_unlock(
0dc0: 6c 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20 20 20 lock);.
0dd0: 20 20 20 20 20 20 20 73 74 61 74 65 20 3d 20 30 state = 0
0de0: 3b 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 ;. } else
0df0: 20 7b 0a 09 09 69 66 20 28 77 72 69 74 65 29 20 {...if (write)
0e00: 7b 0a 09 09 09 72 77 6c 6f 63 6b 5f 77 72 69 74 {....rwlock_writ
0e10: 65 28 6c 6f 63 6b 29 3b 0a 09 09 7d 20 65 6c 73 e(lock);...} els
0e20: 65 20 7b 0a 09 09 09 72 77 6c 6f 63 6b 5f 72 65 e {....rwlock_re
0e30: 61 64 28 6c 6f 63 6b 29 3b 0a 09 09 7d 0a 20 20 ad(lock);...}.
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 74 st
0e50: 61 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 ate = 1;.
0e60: 20 7d 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 }.. retu
0e70: 72 6e 20 73 74 61 74 65 3b 0a 7d 20 0a 0a 23 69 rn state;.} ..#i
0e80: 66 20 30 0a 73 74 61 74 69 63 20 76 6f 69 64 20 f 0.static void
0e90: 74 68 72 65 61 64 5f 6c 6f 63 6b 5f 73 69 67 6e thread_lock_sign
0ea0: 61 6c 28 6d 75 74 65 78 5f 74 20 2a 20 6c 6f 63 al(mutex_t * loc
0eb0: 6b 29 0a 7b 0a 09 74 68 72 65 61 64 5f 74 20 2a k).{..thread_t *
0ec0: 20 72 65 73 75 6d 65 20 3d 20 6c 6f 63 6b 2d 3e resume = lock->
0ed0: 77 61 69 74 69 6e 67 3b 0a 0a 09 69 66 20 28 72 waiting;...if (r
0ee0: 65 73 75 6d 65 29 20 7b 0a 09 09 4c 49 53 54 5f esume) {...LIST_
0ef0: 44 45 4c 45 54 45 28 6c 6f 63 6b 2d 3e 77 61 69 DELETE(lock->wai
0f00: 74 69 6e 67 2c 20 72 65 73 75 6d 65 29 3b 0a 09 ting, resume);..
0f10: 09 74 68 72 65 61 64 5f 72 65 73 75 6d 65 28 72 .thread_resume(r
0f20: 65 73 75 6d 65 29 3b 0a 09 7d 0a 7d 0a 0a 73 74 esume);..}.}..st
0f30: 61 74 69 63 20 76 6f 69 64 20 74 68 72 65 61 64 atic void thread
0f40: 5f 6c 6f 63 6b 5f 77 61 69 74 28 6d 75 74 65 78 _lock_wait(mutex
0f50: 5f 74 20 2a 20 6c 6f 63 6b 29 0a 7b 0a 09 6c 6f _t * lock).{..lo
0f60: 63 6b 2d 3e 77 61 69 74 69 6e 67 20 3d 20 74 68 ck->waiting = th
0f70: 72 65 61 64 5f 71 75 65 75 65 28 6c 6f 63 6b 2d read_queue(lock-
0f80: 3e 77 61 69 74 69 6e 67 2c 20 30 2c 20 54 48 52 >waiting, 0, THR
0f90: 45 41 44 5f 53 4c 45 45 50 49 4e 47 29 3b 0a 09 EAD_SLEEPING);..
0fa0: 2f 2a 20 74 68 72 65 61 64 5f 6c 6f 63 6b 5f 73 /* thread_lock_s
0fb0: 69 67 6e 61 6c 28 6c 6f 63 6b 29 3b 20 2a 2f 0a ignal(lock); */.
0fc0: 09 73 70 69 6e 5f 75 6e 6c 6f 63 6b 28 26 6c 6f .spin_unlock(&lo
0fd0: 63 6b 2d 3e 73 70 69 6e 29 3b 0a 09 74 68 72 65 ck->spin);..thre
0fe0: 61 64 5f 73 63 68 65 64 75 6c 65 28 29 3b 0a 09 ad_schedule();..
0ff0: 73 70 69 6e 5f 6c 6f 63 6b 28 26 6c 6f 63 6b 2d spin_lock(&lock-
1000: 3e 73 70 69 6e 29 3b 0a 7d 0a 0a 6d 75 74 65 78 >spin);.}..mutex
1010: 5f 74 20 2a 20 6d 75 74 65 78 5f 63 72 65 61 74 _t * mutex_creat
1020: 65 28 29 0a 7b 0a 09 72 65 74 75 72 6e 20 73 6c e().{..return sl
1030: 61 62 5f 63 61 6c 6c 6f 63 28 6d 75 74 65 78 65 ab_calloc(mutexe
1040: 73 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 76 6f s);.}.#endif..vo
1050: 69 64 20 6d 75 74 65 78 5f 6c 6f 63 6b 28 6d 75 id mutex_lock(mu
1060: 74 65 78 5f 74 20 2a 20 6c 6f 63 6b 29 0a 7b 0a tex_t * lock).{.
1070: 09 6d 6f 6e 69 74 6f 72 5f 65 6e 74 65 72 28 6c .monitor_enter(l
1080: 6f 63 6b 29 3b 0a 7d 0a 0a 76 6f 69 64 20 6d 75 ock);.}..void mu
1090: 74 65 78 5f 75 6e 6c 6f 63 6b 28 6d 75 74 65 78 tex_unlock(mutex
10a0: 5f 74 20 2a 20 6c 6f 63 6b 29 0a 7b 0a 09 6d 6f _t * lock).{..mo
10b0: 6e 69 74 6f 72 5f 6c 65 61 76 65 28 6c 6f 63 6b nitor_leave(lock
10c0: 29 3b 0a 7d 0a 0a 6d 6f 6e 69 74 6f 72 5f 74 20 );.}..monitor_t
10d0: 2a 20 6d 6f 6e 69 74 6f 72 5f 63 72 65 61 74 65 * monitor_create
10e0: 28 29 0a 7b 0a 09 72 65 74 75 72 6e 20 73 6c 61 ().{..return sla
10f0: 62 5f 63 61 6c 6c 6f 63 28 6d 6f 6e 69 74 6f 72 b_calloc(monitor
1100: 73 29 3b 0a 7d 0a 0a 76 6f 69 64 20 6d 6f 6e 69 s);.}..void moni
1110: 74 6f 72 5f 65 6e 74 65 72 28 6d 6f 6e 69 74 6f tor_enter(monito
1120: 72 5f 74 20 2a 20 6d 6f 6e 69 74 6f 72 29 0a 7b r_t * monitor).{
1130: 0a 09 49 4e 54 45 52 52 55 50 54 5f 4d 4f 4e 49 ..INTERRUPT_MONI
1140: 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 6d 6f 6e TOR_AUTOLOCK(mon
1150: 69 74 6f 72 2d 3e 6c 6f 63 6b 29 20 7b 0a 09 09 itor->lock) {...
1160: 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 thread_t * threa
1170: 64 20 3d 20 61 72 63 68 5f 67 65 74 5f 74 68 72 d = arch_get_thr
1180: 65 61 64 28 29 3b 0a 0a 09 09 77 68 69 6c 65 28 ead();....while(
1190: 6d 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 26 monitor->owner &
11a0: 26 20 74 68 72 65 61 64 20 21 3d 20 6d 6f 6e 69 & thread != moni
11b0: 74 6f 72 2d 3e 6f 77 6e 65 72 29 20 7b 0a 09 09 tor->owner) {...
11c0: 09 2f 2a 20 4c 6f 63 6b 65 64 20 62 79 20 73 6f ./* Locked by so
11d0: 6d 65 6f 6e 65 20 65 6c 73 65 20 2a 2f 0a 09 09 meone else */...
11e0: 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 .interrupt_monit
11f0: 6f 72 5f 77 61 69 74 28 6d 6f 6e 69 74 6f 72 2d or_wait(monitor-
1200: 3e 6c 6f 63 6b 29 3b 0a 09 09 7d 0a 09 09 6d 6f >lock);...}...mo
1210: 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 3d 20 74 nitor->owner = t
1220: 68 72 65 61 64 3b 0a 09 09 6d 6f 6e 69 74 6f 72 hread;...monitor
1230: 2d 3e 63 6f 75 6e 74 2b 2b 3b 0a 09 7d 0a 09 61 ->count++;..}..a
1240: 73 73 65 72 74 28 6d 6f 6e 69 74 6f 72 2d 3e 6f ssert(monitor->o
1250: 77 6e 65 72 20 3d 3d 20 61 72 63 68 5f 67 65 74 wner == arch_get
1260: 5f 74 68 72 65 61 64 28 29 29 3b 0a 7d 0a 0a 76 _thread());.}..v
1270: 6f 69 64 20 6d 6f 6e 69 74 6f 72 5f 6c 65 61 76 oid monitor_leav
1280: 65 28 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d 6f e(monitor_t * mo
1290: 6e 69 74 6f 72 29 0a 7b 0a 09 61 73 73 65 72 74 nitor).{..assert
12a0: 28 6d 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 (monitor->owner
12b0: 3d 3d 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 == arch_get_thre
12c0: 61 64 28 29 29 3b 0a 09 49 4e 54 45 52 52 55 50 ad());..INTERRUP
12d0: 54 5f 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f T_MONITOR_AUTOLO
12e0: 43 4b 28 6d 6f 6e 69 74 6f 72 2d 3e 6c 6f 63 6b CK(monitor->lock
12f0: 29 20 7b 0a 09 09 6d 6f 6e 69 74 6f 72 2d 3e 63 ) {...monitor->c
1300: 6f 75 6e 74 2d 2d 3b 0a 20 20 20 20 20 20 20 20 ount--;.
1310: 20 20 20 20 20 20 20 20 69 66 20 28 30 20 3d 3d if (0 ==
1320: 20 6d 6f 6e 69 74 6f 72 2d 3e 63 6f 75 6e 74 29 monitor->count)
1330: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 {.
1340: 20 20 20 20 20 20 20 20 20 20 20 6d 6f 6e 69 74 monit
1350: 6f 72 2d 3e 6f 77 6e 65 72 20 3d 20 30 3b 0a 20 or->owner = 0;.
1360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1370: 20 20 20 20 20 20 20 69 6e 74 65 72 72 75 70 74 interrupt
1380: 5f 6d 6f 6e 69 74 6f 72 5f 73 69 67 6e 61 6c 28 _monitor_signal(
1390: 6d 6f 6e 69 74 6f 72 2d 3e 6c 6f 63 6b 29 3b 0a monitor->lock);.
13a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
13b0: 7d 0a 09 7d 0a 7d 0a 0a 76 6f 69 64 20 6d 6f 6e }..}.}..void mon
13c0: 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d 65 6f 75 itor_wait_timeou
13d0: 74 28 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d 6f t(monitor_t * mo
13e0: 6e 69 74 6f 72 2c 20 74 69 6d 65 72 73 70 65 63 nitor, timerspec
13f0: 5f 74 20 74 69 6d 65 6f 75 74 29 0a 7b 0a 09 61 _t timeout).{..a
1400: 73 73 65 72 74 28 6d 6f 6e 69 74 6f 72 2d 3e 6f ssert(monitor->o
1410: 77 6e 65 72 20 3d 3d 20 61 72 63 68 5f 67 65 74 wner == arch_get
1420: 5f 74 68 72 65 61 64 28 29 29 3b 0a 09 49 4e 54 _thread());..INT
1430: 45 52 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f 41 ERRUPT_MONITOR_A
1440: 55 54 4f 4c 4f 43 4b 28 6d 6f 6e 69 74 6f 72 2d UTOLOCK(monitor-
1450: 3e 6c 6f 63 6b 29 20 7b 0a 09 09 69 6e 74 20 63 >lock) {...int c
1460: 6f 75 6e 74 20 3d 20 6d 6f 6e 69 74 6f 72 2d 3e ount = monitor->
1470: 63 6f 75 6e 74 3b 0a 09 09 6d 6f 6e 69 74 6f 72 count;...monitor
1480: 2d 3e 63 6f 75 6e 74 20 3d 20 30 3b 0a 09 09 6d ->count = 0;...m
1490: 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 3d 20 onitor->owner =
14a0: 30 3b 0a 09 09 69 6e 74 65 72 72 75 70 74 5f 6d 0;...interrupt_m
14b0: 6f 6e 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d 65 onitor_wait_time
14c0: 6f 75 74 28 6d 6f 6e 69 74 6f 72 2d 3e 6c 6f 63 out(monitor->loc
14d0: 6b 2c 20 74 69 6d 65 6f 75 74 29 3b 0a 09 09 6d k, timeout);...m
14e0: 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 3d 20 onitor->owner =
14f0: 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 arch_get_thread(
1500: 29 3b 0a 09 09 6d 6f 6e 69 74 6f 72 2d 3e 63 6f );...monitor->co
1510: 75 6e 74 20 3d 20 63 6f 75 6e 74 3b 0a 09 7d 0a unt = count;..}.
1520: 7d 0a 0a 76 6f 69 64 20 6d 6f 6e 69 74 6f 72 5f }..void monitor_
1530: 77 61 69 74 28 6d 6f 6e 69 74 6f 72 5f 74 20 2a wait(monitor_t *
1540: 20 6d 6f 6e 69 74 6f 72 29 0a 7b 0a 09 6d 6f 6e monitor).{..mon
1550: 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d 65 6f 75 itor_wait_timeou
1560: 74 28 6d 6f 6e 69 74 6f 72 2c 20 30 29 3b 0a 7d t(monitor, 0);.}
1570: 0a 0a 76 6f 69 64 20 6d 6f 6e 69 74 6f 72 5f 73 ..void monitor_s
1580: 69 67 6e 61 6c 28 6d 6f 6e 69 74 6f 72 5f 74 20 ignal(monitor_t
1590: 2a 20 6d 6f 6e 69 74 6f 72 29 0a 7b 0a 09 61 73 * monitor).{..as
15a0: 73 65 72 74 28 6d 6f 6e 69 74 6f 72 2d 3e 6f 77 sert(monitor->ow
15b0: 6e 65 72 20 3d 3d 20 61 72 63 68 5f 67 65 74 5f ner == arch_get_
15c0: 74 68 72 65 61 64 28 29 29 3b 0a 09 49 4e 54 45 thread());..INTE
15d0: 52 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f 41 55 RRUPT_MONITOR_AU
15e0: 54 4f 4c 4f 43 4b 28 6d 6f 6e 69 74 6f 72 2d 3e TOLOCK(monitor->
15f0: 6c 6f 63 6b 29 20 7b 0a 09 09 69 6e 74 65 72 72 lock) {...interr
1600: 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 73 69 67 6e upt_monitor_sign
1610: 61 6c 28 6d 6f 6e 69 74 6f 72 2d 3e 6c 6f 63 6b al(monitor->lock
1620: 29 3b 0a 09 7d 0a 7d 0a 0a 76 6f 69 64 20 6d 6f );..}.}..void mo
1630: 6e 69 74 6f 72 5f 62 72 6f 61 64 63 61 73 74 28 nitor_broadcast(
1640: 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d 6f 6e 69 monitor_t * moni
1650: 74 6f 72 29 0a 7b 0a 09 61 73 73 65 72 74 28 6d tor).{..assert(m
1660: 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 3d 3d onitor->owner ==
1670: 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 arch_get_thread
1680: 28 29 29 3b 0a 09 49 4e 54 45 52 52 55 50 54 5f ());..INTERRUPT_
1690: 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b MONITOR_AUTOLOCK
16a0: 28 6d 6f 6e 69 74 6f 72 2d 3e 6c 6f 63 6b 29 20 (monitor->lock)
16b0: 7b 0a 09 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f {...interrupt_mo
16c0: 6e 69 74 6f 72 5f 62 72 6f 61 64 63 61 73 74 28 nitor_broadcast(
16d0: 6d 6f 6e 69 74 6f 72 2d 3e 6c 6f 63 6b 29 3b 0a monitor->lock);.
16e0: 09 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 .}.}..static int
16f0: 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 interrupt_monit
1700: 6f 72 5f 64 65 61 64 6c 6f 63 6b 5f 76 69 73 69 or_deadlock_visi
1710: 74 5f 6d 6f 6e 69 74 6f 72 28 6d 61 70 5f 74 20 t_monitor(map_t
1720: 2a 20 76 69 73 69 74 65 64 2c 20 69 6e 74 65 72 * visited, inter
1730: 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 74 20 2a rupt_monitor_t *
1740: 20 6d 6f 6e 69 74 6f 72 29 3b 0a 73 74 61 74 69 monitor);.stati
1750: 63 20 69 6e 74 20 69 6e 74 65 72 72 75 70 74 5f c int interrupt_
1760: 6d 6f 6e 69 74 6f 72 5f 64 65 61 64 6c 6f 63 6b monitor_deadlock
1770: 5f 76 69 73 69 74 5f 74 68 72 65 61 64 28 6d 61 _visit_thread(ma
1780: 70 5f 74 20 2a 20 76 69 73 69 74 65 64 2c 20 74 p_t * visited, t
1790: 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 hread_t * thread
17a0: 29 0a 7b 0a 09 69 66 20 28 74 68 72 65 61 64 20 ).{..if (thread
17b0: 3d 3d 20 6d 61 70 5f 70 75 74 70 70 28 76 69 73 == map_putpp(vis
17c0: 69 74 65 64 2c 20 74 68 72 65 61 64 2c 20 74 68 ited, thread, th
17d0: 72 65 61 64 29 29 20 7b 0a 09 09 72 65 74 75 72 read)) {...retur
17e0: 6e 20 31 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e n 1;..}...return
17f0: 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 interrupt_monit
1800: 6f 72 5f 64 65 61 64 6c 6f 63 6b 5f 76 69 73 69 or_deadlock_visi
1810: 74 5f 6d 6f 6e 69 74 6f 72 28 76 69 73 69 74 65 t_monitor(visite
1820: 64 2c 20 74 68 72 65 61 64 2d 3e 77 61 69 74 69 d, thread->waiti
1830: 6e 67 66 6f 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 ngfor);.}..stati
1840: 63 20 69 6e 74 20 69 6e 74 65 72 72 75 70 74 5f c int interrupt_
1850: 6d 6f 6e 69 74 6f 72 5f 64 65 61 64 6c 6f 63 6b monitor_deadlock
1860: 5f 76 69 73 69 74 5f 6d 6f 6e 69 74 6f 72 28 6d _visit_monitor(m
1870: 61 70 5f 74 20 2a 20 76 69 73 69 74 65 64 2c 20 ap_t * visited,
1880: 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 6f interrupt_monito
1890: 72 5f 74 20 2a 20 6d 6f 6e 69 74 6f 72 29 0a 7b r_t * monitor).{
18a0: 0a 09 69 66 20 28 6d 6f 6e 69 74 6f 72 20 3d 3d ..if (monitor ==
18b0: 20 6d 61 70 5f 70 75 74 70 70 28 76 69 73 69 74 map_putpp(visit
18c0: 65 64 2c 20 6d 6f 6e 69 74 6f 72 2c 20 6d 6f 6e ed, monitor, mon
18d0: 69 74 6f 72 29 29 20 7b 0a 09 09 72 65 74 75 72 itor)) {...retur
18e0: 6e 20 31 3b 0a 09 7d 0a 0a 09 74 68 72 65 61 64 n 1;..}...thread
18f0: 5f 74 20 2a 20 74 68 72 65 61 64 20 3d 20 6d 6f _t * thread = mo
1900: 6e 69 74 6f 72 2d 3e 77 61 69 74 69 6e 67 3b 0a nitor->waiting;.
1910: 09 77 68 69 6c 65 28 74 68 72 65 61 64 29 20 7b .while(thread) {
1920: 0a 09 09 69 66 20 28 69 6e 74 65 72 72 75 70 74 ...if (interrupt
1930: 5f 6d 6f 6e 69 74 6f 72 5f 64 65 61 64 6c 6f 63 _monitor_deadloc
1940: 6b 5f 76 69 73 69 74 5f 74 68 72 65 61 64 28 76 k_visit_thread(v
1950: 69 73 69 74 65 64 2c 20 74 68 72 65 61 64 29 29 isited, thread))
1960: 20 7b 0a 09 09 09 72 65 74 75 72 6e 20 31 3b 0a {....return 1;.
1970: 09 09 7d 0a 09 09 4c 49 53 54 5f 4e 45 58 54 28 ..}...LIST_NEXT(
1980: 6d 6f 6e 69 74 6f 72 2d 3e 77 61 69 74 69 6e 67 monitor->waiting
1990: 2c 20 74 68 72 65 61 64 29 3b 0a 09 7d 0a 0a 09 , thread);..}...
19a0: 72 65 74 75 72 6e 20 69 6e 74 65 72 72 75 70 74 return interrupt
19b0: 5f 6d 6f 6e 69 74 6f 72 5f 64 65 61 64 6c 6f 63 _monitor_deadloc
19c0: 6b 5f 76 69 73 69 74 5f 74 68 72 65 61 64 28 76 k_visit_thread(v
19d0: 69 73 69 74 65 64 2c 20 6d 6f 6e 69 74 6f 72 2d isited, monitor-
19e0: 3e 6f 77 6e 65 72 29 3b 0a 7d 0a 0a 76 6f 69 64 >owner);.}..void
19f0: 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 interrupt_monit
1a00: 6f 72 5f 65 6e 74 65 72 28 69 6e 74 65 72 72 75 or_enter(interru
1a10: 70 74 5f 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d pt_monitor_t * m
1a20: 6f 6e 69 74 6f 72 29 0a 7b 0a 09 69 6e 74 65 72 onitor).{..inter
1a30: 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 74 20 2a rupt_monitor_t *
1a40: 20 77 61 69 74 69 6e 67 66 6f 72 20 3d 20 61 72 waitingfor = ar
1a50: 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 2d ch_get_thread()-
1a60: 3e 77 61 69 74 69 6e 67 66 6f 72 3b 0a 09 61 72 >waitingfor;..ar
1a70: 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 2d ch_get_thread()-
1a80: 3e 77 61 69 74 69 6e 67 66 6f 72 20 3d 20 6d 6f >waitingfor = mo
1a90: 6e 69 74 6f 72 3b 0a 23 69 66 20 30 0a 09 73 70 nitor;.#if 0..sp
1aa0: 69 6e 5f 6c 6f 63 6b 28 26 6d 6f 6e 69 74 6f 72 in_lock(&monitor
1ab0: 2d 3e 73 70 69 6e 29 3b 0a 23 65 6c 73 65 0a 09 ->spin);.#else..
1ac0: 69 6e 74 20 61 74 74 65 6d 70 74 73 20 3d 20 30 int attempts = 0
1ad0: 3b 0a 09 77 68 69 6c 65 28 30 20 3d 3d 20 73 70 ;..while(0 == sp
1ae0: 69 6e 5f 74 72 79 6c 6f 63 6b 28 26 6d 6f 6e 69 in_trylock(&moni
1af0: 74 6f 72 2d 3e 73 70 69 6e 29 29 20 7b 0a 09 09 tor->spin)) {...
1b00: 61 74 74 65 6d 70 74 73 2b 2b 3b 0a 09 09 69 66 attempts++;...if
1b10: 20 28 30 20 3d 3d 20 28 61 74 74 65 6d 70 74 73 (0 == (attempts
1b20: 20 26 20 30 78 66 66 66 66 29 29 20 7b 0a 09 09 & 0xffff)) {...
1b30: 09 2f 2a 20 54 72 79 20 74 6f 20 64 65 74 65 63 ./* Try to detec
1b40: 74 20 64 65 61 64 6c 6f 63 6b 20 2a 2f 0a 09 09 t deadlock */...
1b50: 09 6d 61 70 5f 74 20 2a 20 76 69 73 69 74 65 64 .map_t * visited
1b60: 20 3d 20 74 72 65 61 70 5f 6e 65 77 28 4e 55 4c = treap_new(NUL
1b70: 4c 29 3b 0a 09 09 09 69 66 20 28 69 6e 74 65 72 L);....if (inter
1b80: 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 64 65 61 rupt_monitor_dea
1b90: 64 6c 6f 63 6b 5f 76 69 73 69 74 5f 74 68 72 65 dlock_visit_thre
1ba0: 61 64 28 76 69 73 69 74 65 64 2c 20 61 72 63 68 ad(visited, arch
1bb0: 5f 67 65 74 5f 74 68 72 65 61 64 28 29 29 29 20 _get_thread()))
1bc0: 7b 0a 09 09 09 09 74 68 72 65 61 64 5f 79 69 65 {.....thread_yie
1bd0: 6c 64 28 29 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 ld();....}...}..
1be0: 7d 0a 23 65 6e 64 69 66 0a 09 61 72 63 68 5f 67 }.#endif..arch_g
1bf0: 65 74 5f 74 68 72 65 61 64 28 29 2d 3e 77 61 69 et_thread()->wai
1c00: 74 69 6e 67 66 6f 72 20 3d 20 77 61 69 74 69 6e tingfor = waitin
1c10: 67 66 6f 72 3b 0a 09 6d 6f 6e 69 74 6f 72 2d 3e gfor;..monitor->
1c20: 6f 77 6e 65 72 20 3d 20 61 72 63 68 5f 67 65 74 owner = arch_get
1c30: 5f 74 68 72 65 61 64 28 29 3b 0a 09 61 73 73 65 _thread();..asse
1c40: 72 74 28 6d 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 rt(monitor->owne
1c50: 72 20 3d 3d 20 61 72 63 68 5f 67 65 74 5f 74 68 r == arch_get_th
1c60: 72 65 61 64 28 29 29 3b 0a 7d 0a 0a 76 6f 69 64 read());.}..void
1c70: 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 interrupt_monit
1c80: 6f 72 5f 6c 65 61 76 65 28 69 6e 74 65 72 72 75 or_leave(interru
1c90: 70 74 5f 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d pt_monitor_t * m
1ca0: 6f 6e 69 74 6f 72 29 0a 7b 0a 09 61 73 73 65 72 onitor).{..asser
1cb0: 74 28 6d 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 t(monitor->owner
1cc0: 20 3d 3d 20 61 72 63 68 5f 67 65 74 5f 74 68 72 == arch_get_thr
1cd0: 65 61 64 28 29 29 3b 0a 09 6d 6f 6e 69 74 6f 72 ead());..monitor
1ce0: 2d 3e 6f 77 6e 65 72 20 3d 20 30 3b 0a 09 73 70 ->owner = 0;..sp
1cf0: 69 6e 5f 75 6e 6c 6f 63 6b 28 26 6d 6f 6e 69 74 in_unlock(&monit
1d00: 6f 72 2d 3e 73 70 69 6e 29 3b 0a 7d 0a 0a 74 79 or->spin);.}..ty
1d10: 70 65 64 65 66 20 73 74 72 75 63 74 20 69 6e 74 pedef struct int
1d20: 65 72 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 77 errupt_monitor_w
1d30: 61 69 74 5f 74 69 6d 65 6f 75 74 5f 74 20 7b 0a ait_timeout_t {.
1d40: 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 .interrupt_monit
1d50: 6f 72 5f 74 20 2a 20 6d 6f 6e 69 74 6f 72 3b 0a or_t * monitor;.
1d60: 09 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 .thread_t * thre
1d70: 61 64 3b 0a 7d 20 69 6e 74 65 72 72 75 70 74 5f ad;.} interrupt_
1d80: 6d 6f 6e 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d monitor_wait_tim
1d90: 65 6f 75 74 5f 74 3b 0a 0a 0a 73 74 61 74 69 63 eout_t;...static
1da0: 20 76 6f 69 64 20 69 6e 74 65 72 72 75 70 74 5f void interrupt_
1db0: 6d 6f 6e 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d monitor_wait_tim
1dc0: 65 6f 75 74 5f 74 68 72 65 61 64 28 76 6f 69 64 eout_thread(void
1dd0: 20 2a 20 70 29 0a 7b 0a 09 69 6e 74 65 72 72 75 * p).{..interru
1de0: 70 74 5f 6d 6f 6e 69 74 6f 72 5f 77 61 69 74 5f pt_monitor_wait_
1df0: 74 69 6d 65 6f 75 74 5f 74 20 2a 20 74 69 6d 65 timeout_t * time
1e00: 6f 75 74 20 3d 20 70 3b 0a 0a 09 49 4e 54 45 52 out = p;...INTER
1e10: 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f 41 55 54 RUPT_MONITOR_AUT
1e20: 4f 4c 4f 43 4b 28 74 69 6d 65 6f 75 74 2d 3e 6d OLOCK(timeout->m
1e30: 6f 6e 69 74 6f 72 29 20 7b 0a 09 09 74 68 72 65 onitor) {...thre
1e40: 61 64 5f 74 20 2a 20 74 68 72 65 61 64 20 3d 20 ad_t * thread =
1e50: 74 69 6d 65 6f 75 74 2d 3e 6d 6f 6e 69 74 6f 72 timeout->monitor
1e60: 2d 3e 77 61 69 74 69 6e 67 3b 0a 0a 09 09 77 68 ->waiting;....wh
1e70: 69 6c 65 28 74 68 72 65 61 64 29 20 7b 0a 09 09 ile(thread) {...
1e80: 09 69 66 20 28 74 68 72 65 61 64 20 3d 3d 20 74 .if (thread == t
1e90: 69 6d 65 6f 75 74 2d 3e 74 68 72 65 61 64 29 20 imeout->thread)
1ea0: 7b 0a 09 09 09 09 4c 49 53 54 5f 44 45 4c 45 54 {.....LIST_DELET
1eb0: 45 28 74 69 6d 65 6f 75 74 2d 3e 6d 6f 6e 69 74 E(timeout->monit
1ec0: 6f 72 2d 3e 77 61 69 74 69 6e 67 2c 20 74 68 72 or->waiting, thr
1ed0: 65 61 64 29 3b 0a 09 09 09 09 74 68 72 65 61 64 ead);.....thread
1ee0: 5f 69 6e 74 65 72 72 75 70 74 28 74 68 72 65 61 _interrupt(threa
1ef0: 64 29 3b 0a 09 09 09 09 74 68 72 65 61 64 5f 72 d);.....thread_r
1f00: 65 73 75 6d 65 28 74 68 72 65 61 64 29 3b 0a 09 esume(thread);..
1f10: 09 09 09 74 68 72 65 61 64 20 3d 20 30 3b 0a 09 ...thread = 0;..
1f20: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 4c ..} else {.....L
1f30: 49 53 54 5f 4e 45 58 54 28 74 69 6d 65 6f 75 74 IST_NEXT(timeout
1f40: 2d 3e 6d 6f 6e 69 74 6f 72 2d 3e 77 61 69 74 69 ->monitor->waiti
1f50: 6e 67 2c 20 74 68 72 65 61 64 29 3b 0a 09 09 09 ng, thread);....
1f60: 7d 0a 09 09 7d 0a 09 7d 0a 7d 0a 0a 76 6f 69 64 }...}..}.}..void
1f70: 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 interrupt_monit
1f80: 6f 72 5f 77 61 69 74 5f 74 69 6d 65 6f 75 74 28 or_wait_timeout(
1f90: 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 6f interrupt_monito
1fa0: 72 5f 74 20 2a 20 6d 6f 6e 69 74 6f 72 2c 20 74 r_t * monitor, t
1fb0: 69 6d 65 72 73 70 65 63 5f 74 20 74 69 6d 65 6f imerspec_t timeo
1fc0: 75 74 29 0a 7b 0a 09 61 73 73 65 72 74 28 6d 6f ut).{..assert(mo
1fd0: 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 3d 3d 20 nitor->owner ==
1fe0: 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 arch_get_thread(
1ff0: 29 29 3b 0a 09 69 6e 74 65 72 72 75 70 74 5f 6d ));..interrupt_m
2000: 6f 6e 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d 65 onitor_wait_time
2010: 6f 75 74 5f 74 20 74 69 6d 65 6f 75 74 5f 74 68 out_t timeout_th
2020: 72 65 61 64 20 3d 20 7b 20 6d 6f 6e 69 74 6f 72 read = { monitor
2030: 2c 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 , arch_get_threa
2040: 64 28 29 20 7d 3b 0a 09 74 69 6d 65 72 5f 65 76 d() };..timer_ev
2050: 65 6e 74 5f 74 20 2a 20 74 69 6d 65 72 3b 0a 09 ent_t * timer;..
2060: 69 66 20 28 74 69 6d 65 6f 75 74 29 20 7b 0a 09 if (timeout) {..
2070: 09 74 69 6d 65 72 5f 73 65 74 28 6d 6f 6e 69 74 .timer_set(monit
2080: 6f 72 2d 3e 74 69 6d 65 72 2c 20 74 69 6d 65 6f or->timer, timeo
2090: 75 74 2c 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f ut, interrupt_mo
20a0: 6e 69 74 6f 72 5f 77 61 69 74 5f 74 69 6d 65 6f nitor_wait_timeo
20b0: 75 74 5f 74 68 72 65 61 64 2c 20 26 74 69 6d 65 ut_thread, &time
20c0: 6f 75 74 5f 74 68 72 65 61 64 29 3b 0a 09 7d 0a out_thread);..}.
20d0: 09 6d 6f 6e 69 74 6f 72 2d 3e 77 61 69 74 69 6e .monitor->waitin
20e0: 67 20 3d 20 74 68 72 65 61 64 5f 71 75 65 75 65 g = thread_queue
20f0: 28 6d 6f 6e 69 74 6f 72 2d 3e 77 61 69 74 69 6e (monitor->waitin
2100: 67 2c 20 30 2c 20 54 48 52 45 41 44 5f 53 4c 45 g, 0, THREAD_SLE
2110: 45 50 49 4e 47 29 3b 0a 09 69 6e 74 65 72 72 75 EPING);..interru
2120: 70 74 5f 6d 6f 6e 69 74 6f 72 5f 6c 65 61 76 65 pt_monitor_leave
2130: 28 6d 6f 6e 69 74 6f 72 29 3b 0a 09 74 68 72 65 (monitor);..thre
2140: 61 64 5f 73 63 68 65 64 75 6c 65 28 29 3b 0a 0a ad_schedule();..
2150: 09 2f 2a 20 43 68 65 63 6b 20 66 6f 72 20 74 69 ./* Check for ti
2160: 6d 65 6f 75 74 20 2a 2f 0a 09 69 66 20 28 74 69 meout */..if (ti
2170: 6d 65 6f 75 74 29 20 7b 0a 09 09 74 69 6d 65 72 meout) {...timer
2180: 5f 64 65 6c 65 74 65 28 6d 6f 6e 69 74 6f 72 2d _delete(monitor-
2190: 3e 74 69 6d 65 72 29 3b 0a 09 09 69 66 20 28 74 >timer);...if (t
21a0: 68 72 65 61 64 5f 69 6e 74 65 72 72 75 70 74 65 hread_interrupte
21b0: 64 28 29 29 20 7b 0a 09 09 09 4b 54 48 52 4f 57 d()) {....KTHROW
21c0: 28 54 69 6d 65 6f 75 74 45 78 63 65 70 74 69 6f (TimeoutExceptio
21d0: 6e 2c 20 22 54 69 6d 65 6f 75 74 22 29 3b 0a 09 n, "Timeout");..
21e0: 09 7d 0a 09 7d 0a 09 69 6e 74 65 72 72 75 70 74 .}..}..interrupt
21f0: 5f 6d 6f 6e 69 74 6f 72 5f 65 6e 74 65 72 28 6d _monitor_enter(m
2200: 6f 6e 69 74 6f 72 29 3b 0a 7d 0a 0a 76 6f 69 64 onitor);.}..void
2210: 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 interrupt_monit
2220: 6f 72 5f 77 61 69 74 28 69 6e 74 65 72 72 75 70 or_wait(interrup
2230: 74 5f 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d 6f t_monitor_t * mo
2240: 6e 69 74 6f 72 29 0a 7b 0a 09 61 73 73 65 72 74 nitor).{..assert
2250: 28 6d 6f 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 (monitor->owner
2260: 3d 3d 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 == arch_get_thre
2270: 61 64 28 29 29 3b 0a 09 69 6e 74 65 72 72 75 70 ad());..interrup
2280: 74 5f 6d 6f 6e 69 74 6f 72 5f 77 61 69 74 5f 74 t_monitor_wait_t
2290: 69 6d 65 6f 75 74 28 6d 6f 6e 69 74 6f 72 2c 20 imeout(monitor,
22a0: 30 29 3b 0a 7d 0a 0a 76 6f 69 64 20 69 6e 74 65 0);.}..void inte
22b0: 72 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 73 69 rrupt_monitor_si
22c0: 67 6e 61 6c 28 69 6e 74 65 72 72 75 70 74 5f 6d gnal(interrupt_m
22d0: 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d 6f 6e 69 74 onitor_t * monit
22e0: 6f 72 29 0a 7b 0a 09 61 73 73 65 72 74 28 6d 6f or).{..assert(mo
22f0: 6e 69 74 6f 72 2d 3e 6f 77 6e 65 72 20 3d 3d 20 nitor->owner ==
2300: 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 arch_get_thread(
2310: 29 29 3b 0a 0a 09 74 68 72 65 61 64 5f 74 20 2a ));...thread_t *
2320: 20 72 65 73 75 6d 65 20 3d 20 6d 6f 6e 69 74 6f resume = monito
2330: 72 2d 3e 77 61 69 74 69 6e 67 3b 0a 0a 09 69 66 r->waiting;...if
2340: 20 28 72 65 73 75 6d 65 29 20 7b 0a 09 09 4c 49 (resume) {...LI
2350: 53 54 5f 44 45 4c 45 54 45 28 6d 6f 6e 69 74 6f ST_DELETE(monito
2360: 72 2d 3e 77 61 69 74 69 6e 67 2c 20 72 65 73 75 r->waiting, resu
2370: 6d 65 29 3b 0a 09 09 74 68 72 65 61 64 5f 72 65 me);...thread_re
2380: 73 75 6d 65 28 72 65 73 75 6d 65 29 3b 0a 09 7d sume(resume);..}
2390: 0a 7d 0a 0a 76 6f 69 64 20 69 6e 74 65 72 72 75 .}..void interru
23a0: 70 74 5f 6d 6f 6e 69 74 6f 72 5f 62 72 6f 61 64 pt_monitor_broad
23b0: 63 61 73 74 28 69 6e 74 65 72 72 75 70 74 5f 6d cast(interrupt_m
23c0: 6f 6e 69 74 6f 72 5f 74 20 2a 20 6d 6f 6e 69 74 onitor_t * monit
23d0: 6f 72 29 0a 7b 0a 09 77 68 69 6c 65 28 6d 6f 6e or).{..while(mon
23e0: 69 74 6f 72 2d 3e 77 61 69 74 69 6e 67 29 20 7b itor->waiting) {
23f0: 0a 09 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e ...interrupt_mon
2400: 69 74 6f 72 5f 73 69 67 6e 61 6c 28 6d 6f 6e 69 itor_signal(moni
2410: 74 6f 72 29 3b 0a 09 7d 0a 7d 0a 0a 73 74 61 74 tor);..}.}..stat
2420: 69 63 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e ic interrupt_mon
2430: 69 74 6f 72 5f 74 20 6c 6f 63 6b 73 5b 33 32 5d itor_t locks[32]
2440: 20 3d 20 7b 30 7d 3b 0a 73 74 61 74 69 63 20 76 = {0};.static v
2450: 6f 69 64 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f oid interrupt_mo
2460: 6e 69 74 6f 72 5f 69 72 71 5f 74 72 69 67 67 65 nitor_irq_trigge
2470: 72 28 69 6e 74 20 69 72 71 29 0a 7b 0a 09 49 4e r(int irq).{..IN
2480: 54 45 52 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f TERRUPT_MONITOR_
2490: 41 55 54 4f 4c 4f 43 4b 28 6c 6f 63 6b 73 2b 69 AUTOLOCK(locks+i
24a0: 72 71 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 rq) {.
24b0: 20 20 20 20 20 20 69 6e 74 65 72 72 75 70 74 5f interrupt_
24c0: 6d 6f 6e 69 74 6f 72 5f 62 72 6f 61 64 63 61 73 monitor_broadcas
24d0: 74 28 6c 6f 63 6b 73 2b 69 72 71 29 3b 0a 20 20 t(locks+irq);.
24e0: 20 20 20 20 20 20 7d 0a 7d 0a 0a 23 69 66 20 30 }.}..#if 0
24f0: 0a 73 74 61 74 69 63 20 6d 6f 6e 69 74 6f 72 5f .static monitor_
2500: 74 20 2a 20 74 68 72 65 61 64 5f 6d 6f 6e 69 74 t * thread_monit
2510: 6f 72 5f 67 65 74 28 76 6f 69 64 20 2a 20 70 29 or_get(void * p)
2520: 0a 7b 0a 09 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 .{..mutex_lock(&
2530: 6c 6f 63 6b 74 61 62 6c 65 6c 6f 63 6b 29 3b 0a locktablelock);.
2540: 09 69 66 20 28 30 20 3d 3d 20 6c 6f 63 6b 74 61 .if (0 == lockta
2550: 62 6c 65 29 20 7b 0a 09 09 6c 6f 63 6b 74 61 62 ble) {...locktab
2560: 6c 65 20 3d 20 74 72 65 65 5f 6e 65 77 28 30 2c le = tree_new(0,
2570: 20 54 52 45 45 5f 53 50 4c 41 59 29 3b 0a 09 7d TREE_SPLAY);..}
2580: 0a 0a 09 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6c ...monitor_t * l
2590: 6f 63 6b 20 3d 20 6d 61 70 5f 67 65 74 70 70 28 ock = map_getpp(
25a0: 6c 6f 63 6b 74 61 62 6c 65 2c 20 70 29 3b 0a 09 locktable, p);..
25b0: 69 66 20 28 30 20 3d 3d 20 6c 6f 63 6b 29 20 7b if (0 == lock) {
25c0: 0a 09 09 6c 6f 63 6b 20 3d 20 73 6c 61 62 5f 63 ...lock = slab_c
25d0: 61 6c 6c 6f 63 28 6d 6f 6e 69 74 6f 72 73 29 3b alloc(monitors);
25e0: 0a 09 09 6d 61 70 5f 70 75 74 70 70 28 6c 6f 63 ...map_putpp(loc
25f0: 6b 74 61 62 6c 65 2c 20 70 2c 20 6c 6f 63 6b 29 ktable, p, lock)
2600: 3b 0a 09 7d 0a 0a 09 6d 75 74 65 78 5f 75 6e 6c ;..}...mutex_unl
2610: 6f 63 6b 28 26 6c 6f 63 6b 74 61 62 6c 65 6c 6f ock(&locktablelo
2620: 63 6b 29 3b 0a 0a 09 72 65 74 75 72 6e 20 6c 6f ck);...return lo
2630: 63 6b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e ck;.}..static in
2640: 74 20 74 68 72 65 61 64 5f 74 72 79 6c 6f 63 6b t thread_trylock
2650: 5f 69 6e 74 65 72 6e 61 6c 28 6d 75 74 65 78 5f _internal(mutex_
2660: 74 20 2a 20 6c 6f 63 6b 29 0a 7b 0a 09 69 66 20 t * lock).{..if
2670: 28 30 20 3d 3d 20 6c 6f 63 6b 2d 3e 63 6f 75 6e (0 == lock->coun
2680: 74 29 20 7b 0a 09 09 2f 2a 20 4e 6f 74 20 69 6e t) {.../* Not in
2690: 20 75 73 65 2c 20 6d 61 72 6b 20 69 74 20 61 73 use, mark it as
26a0: 20 75 73 65 64 20 61 6e 64 20 6c 6f 63 6b 65 64 used and locked
26b0: 20 2a 2f 0a 09 09 6c 6f 63 6b 2d 3e 63 6f 75 6e */...lock->coun
26c0: 74 20 3d 20 31 3b 0a 09 09 6c 6f 63 6b 2d 3e 6f t = 1;...lock->o
26d0: 77 6e 65 72 20 3d 20 61 72 63 68 5f 67 65 74 5f wner = arch_get_
26e0: 74 68 72 65 61 64 28 29 3b 0a 09 09 73 70 69 6e thread();...spin
26f0: 5f 75 6e 6c 6f 63 6b 28 26 6c 6f 63 6b 2d 3e 73 _unlock(&lock->s
2700: 70 69 6e 29 3b 0a 09 09 72 65 74 75 72 6e 20 31 pin);...return 1
2710: 3b 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 6c 6f ;..} else if (lo
2720: 63 6b 2d 3e 6f 77 6e 65 72 20 3d 3d 20 61 72 63 ck->owner == arc
2730: 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 29 20 h_get_thread())
2740: 7b 0a 09 09 2f 2a 20 52 65 63 75 72 73 69 76 65 {.../* Recursive
2750: 20 6c 6f 63 6b 2c 20 69 6e 63 72 65 61 73 65 20 lock, increase
2760: 63 6f 75 6e 74 20 2a 2f 0a 09 09 6c 6f 63 6b 2d count */...lock-
2770: 3e 63 6f 75 6e 74 2b 2b 3b 0a 09 09 73 70 69 6e >count++;...spin
2780: 5f 75 6e 6c 6f 63 6b 28 26 6c 6f 63 6b 2d 3e 73 _unlock(&lock->s
2790: 70 69 6e 29 3b 0a 09 09 72 65 74 75 72 6e 20 31 pin);...return 1
27a0: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 20 30 3b ;..}...return 0;
27b0: 0a 7d 0a 23 65 6e 64 69 66 0a 0a 76 6f 69 64 20 .}.#endif..void
27c0: 72 77 6c 6f 63 6b 5f 72 65 61 64 28 72 77 6c 6f rwlock_read(rwlo
27d0: 63 6b 5f 74 20 2a 20 6c 6f 63 6b 29 0a 7b 0a 09 ck_t * lock).{..
27e0: 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b MONITOR_AUTOLOCK
27f0: 28 6c 6f 63 6b 2d 3e 6c 6f 63 6b 29 20 7b 0a 09 (lock->lock) {..
2800: 09 69 66 20 28 61 72 63 68 5f 67 65 74 5f 74 68 .if (arch_get_th
2810: 72 65 61 64 28 29 20 3d 3d 20 6c 6f 63 6b 2d 3e read() == lock->
2820: 77 72 69 74 65 72 29 20 7b 0a 09 09 09 2f 2a 20 writer) {..../*
2830: 57 65 20 61 6c 72 65 61 64 79 20 68 61 76 65 20 We already have
2840: 61 20 77 72 69 74 65 20 6c 6f 63 6b 2c 20 67 69 a write lock, gi
2850: 76 65 20 69 74 20 75 70 20 2a 2f 0a 09 09 09 6c ve it up */....l
2860: 6f 63 6b 2d 3e 77 72 69 74 65 72 20 3d 20 30 3b ock->writer = 0;
2870: 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 77 ...} else {....w
2880: 68 69 6c 65 28 6c 6f 63 6b 2d 3e 77 72 69 74 65 hile(lock->write
2890: 72 29 20 7b 0a 09 09 09 09 6d 6f 6e 69 74 6f 72 r) {.....monitor
28a0: 5f 77 61 69 74 28 6c 6f 63 6b 2d 3e 6c 6f 63 6b _wait(lock->lock
28b0: 29 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 09 6c 6f );....}...}...lo
28c0: 63 6b 2d 3e 72 65 61 64 63 6f 75 6e 74 2b 2b 3b ck->readcount++;
28d0: 0a 09 7d 0a 7d 0a 0a 76 6f 69 64 20 72 77 6c 6f ..}.}..void rwlo
28e0: 63 6b 5f 77 72 69 74 65 28 72 77 6c 6f 63 6b 5f ck_write(rwlock_
28f0: 74 20 2a 20 6c 6f 63 6b 29 0a 7b 0a 09 74 68 72 t * lock).{..thr
2900: 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 20 3d ead_t * thread =
2910: 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 arch_get_thread
2920: 28 29 3b 0a 09 4d 4f 4e 49 54 4f 52 5f 41 55 54 ();..MONITOR_AUT
2930: 4f 4c 4f 43 4b 28 6c 6f 63 6b 2d 3e 6c 6f 63 6b OLOCK(lock->lock
2940: 29 20 7b 0a 09 09 2f 2a 20 4e 6f 74 20 61 6c 72 ) {.../* Not alr
2950: 65 61 64 79 20 61 20 72 65 61 64 65 72 2c 20 77 eady a reader, w
2960: 61 69 74 20 75 6e 74 69 6c 20 6e 6f 20 77 72 69 ait until no wri
2970: 74 65 72 20 6f 72 20 72 65 61 64 65 72 73 20 2a ter or readers *
2980: 2f 0a 09 09 77 68 69 6c 65 28 6c 6f 63 6b 2d 3e /...while(lock->
2990: 72 65 61 64 63 6f 75 6e 74 20 7c 7c 20 6c 6f 63 readcount || loc
29a0: 6b 2d 3e 77 72 69 74 65 72 29 20 7b 0a 09 09 09 k->writer) {....
29b0: 6d 6f 6e 69 74 6f 72 5f 77 61 69 74 28 6c 6f 63 monitor_wait(loc
29c0: 6b 2d 3e 6c 6f 63 6b 29 3b 0a 09 09 7d 0a 09 09 k->lock);...}...
29d0: 6c 6f 63 6b 2d 3e 77 72 69 74 65 72 20 3d 20 74 lock->writer = t
29e0: 68 72 65 61 64 3b 0a 09 7d 0a 7d 0a 0a 76 6f 69 hread;..}.}..voi
29f0: 64 20 72 77 6c 6f 63 6b 5f 65 73 63 61 6c 61 74 d rwlock_escalat
2a00: 65 28 72 77 6c 6f 63 6b 5f 74 20 2a 20 6c 6f 63 e(rwlock_t * loc
2a10: 6b 29 0a 7b 0a 09 74 68 72 65 61 64 5f 74 20 2a k).{..thread_t *
2a20: 20 74 68 72 65 61 64 20 3d 20 61 72 63 68 5f 67 thread = arch_g
2a30: 65 74 5f 74 68 72 65 61 64 28 29 3b 0a 09 4d 4f et_thread();..MO
2a40: 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 6c NITOR_AUTOLOCK(l
2a50: 6f 63 6b 2d 3e 6c 6f 63 6b 29 20 7b 0a 09 09 77 ock->lock) {...w
2a60: 68 69 6c 65 28 6c 6f 63 6b 2d 3e 72 65 61 64 63 hile(lock->readc
2a70: 6f 75 6e 74 20 3e 20 31 20 7c 7c 20 6c 6f 63 6b ount > 1 || lock
2a80: 2d 3e 77 72 69 74 65 72 29 20 7b 0a 09 09 09 6d ->writer) {....m
2a90: 6f 6e 69 74 6f 72 5f 77 61 69 74 28 6c 6f 63 6b onitor_wait(lock
2aa0: 2d 3e 6c 6f 63 6b 29 3b 0a 09 09 7d 0a 0a 09 09 ->lock);...}....
2ab0: 6c 6f 63 6b 2d 3e 72 65 61 64 63 6f 75 6e 74 20 lock->readcount
2ac0: 3d 20 30 3b 0a 09 09 6c 6f 63 6b 2d 3e 77 72 69 = 0;...lock->wri
2ad0: 74 65 72 20 3d 20 74 68 72 65 61 64 3b 0a 09 7d ter = thread;..}
2ae0: 0a 7d 0a 0a 76 6f 69 64 20 72 77 6c 6f 63 6b 5f .}..void rwlock_
2af0: 75 6e 6c 6f 63 6b 28 72 77 6c 6f 63 6b 5f 74 20 unlock(rwlock_t
2b00: 2a 20 6c 6f 63 6b 29 0a 7b 0a 09 74 68 72 65 61 * lock).{..threa
2b10: 64 5f 74 20 2a 20 74 68 72 65 61 64 20 3d 20 61 d_t * thread = a
2b20: 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 rch_get_thread()
2b30: 3b 0a 09 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c ;..MONITOR_AUTOL
2b40: 4f 43 4b 28 6c 6f 63 6b 2d 3e 6c 6f 63 6b 29 20 OCK(lock->lock)
2b50: 7b 0a 09 09 69 66 20 28 74 68 72 65 61 64 20 3d {...if (thread =
2b60: 3d 20 6c 6f 63 6b 2d 3e 77 72 69 74 65 72 29 20 = lock->writer)
2b70: 7b 0a 09 09 09 6c 6f 63 6b 2d 3e 77 72 69 74 65 {....lock->write
2b80: 72 20 3d 20 30 3b 0a 09 09 7d 20 65 6c 73 65 20 r = 0;...} else
2b90: 7b 0a 09 09 09 6c 6f 63 6b 2d 3e 72 65 61 64 63 {....lock->readc
2ba0: 6f 75 6e 74 2d 2d 3b 0a 09 09 7d 0a 09 09 6d 6f ount--;...}...mo
2bb0: 6e 69 74 6f 72 5f 62 72 6f 61 64 63 61 73 74 28 nitor_broadcast(
2bc0: 6c 6f 63 6b 2d 3e 6c 6f 63 6b 29 3b 0a 09 7d 0a lock->lock);..}.
2bd0: 7d 0a 0a 23 69 66 20 30 0a 69 6e 74 20 74 68 72 }..#if 0.int thr
2be0: 65 61 64 5f 74 72 79 70 6c 6f 63 6b 28 76 6f 69 ead_tryplock(voi
2bf0: 64 20 2a 20 70 29 0a 7b 0a 09 6d 75 74 65 78 5f d * p).{..mutex_
2c00: 74 20 2a 20 6c 6f 63 6b 20 3d 20 74 68 72 65 61 t * lock = threa
2c10: 64 5f 6d 6f 6e 69 74 6f 72 5f 67 65 74 28 70 29 d_monitor_get(p)
2c20: 3b 0a 0a 09 72 65 74 75 72 6e 20 74 68 72 65 61 ;...return threa
2c30: 64 5f 74 72 79 6c 6f 63 6b 5f 69 6e 74 65 72 6e d_trylock_intern
2c40: 61 6c 28 6c 6f 63 6b 29 3b 0a 7d 0a 0a 76 6f 69 al(lock);.}..voi
2c50: 64 20 74 68 72 65 61 64 5f 6c 6f 63 6b 28 76 6f d thread_lock(vo
2c60: 69 64 20 2a 20 70 29 0a 7b 0a 09 6d 6f 6e 69 74 id * p).{..monit
2c70: 6f 72 5f 74 20 2a 20 6c 6f 63 6b 20 3d 20 74 68 or_t * lock = th
2c80: 72 65 61 64 5f 6d 6f 6e 69 74 6f 72 5f 67 65 74 read_monitor_get
2c90: 28 70 29 3b 0a 0a 09 6d 6f 6e 69 74 6f 72 5f 65 (p);...monitor_e
2ca0: 6e 74 65 72 28 6c 6f 63 6b 29 3b 0a 7d 0a 0a 76 nter(lock);.}..v
2cb0: 6f 69 64 20 74 68 72 65 61 64 5f 75 6e 6c 6f 63 oid thread_unloc
2cc0: 6b 28 76 6f 69 64 20 2a 70 29 0a 7b 0a 09 6d 6f k(void *p).{..mo
2cd0: 6e 69 74 6f 72 5f 74 20 2a 20 6c 6f 63 6b 20 3d nitor_t * lock =
2ce0: 20 74 68 72 65 61 64 5f 6d 6f 6e 69 74 6f 72 5f thread_monitor_
2cf0: 67 65 74 28 70 29 3b 0a 0a 09 6d 6f 6e 69 74 6f get(p);...monito
2d00: 72 5f 6c 65 61 76 65 28 6c 6f 63 6b 29 3b 0a 7d r_leave(lock);.}
2d10: 0a 0a 76 6f 69 64 20 74 68 72 65 61 64 5f 73 69 ..void thread_si
2d20: 67 6e 61 6c 28 76 6f 69 64 20 2a 70 29 0a 7b 0a gnal(void *p).{.
2d30: 09 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 6c 6f 63 .monitor_t * loc
2d40: 6b 20 3d 20 74 68 72 65 61 64 5f 6d 6f 6e 69 74 k = thread_monit
2d50: 6f 72 5f 67 65 74 28 70 29 3b 0a 0a 09 6d 6f 6e or_get(p);...mon
2d60: 69 74 6f 72 5f 73 69 67 6e 61 6c 28 6c 6f 63 6b itor_signal(lock
2d70: 29 3b 0a 7d 0a 0a 76 6f 69 64 20 74 68 72 65 61 );.}..void threa
2d80: 64 5f 62 72 6f 61 64 63 61 73 74 28 76 6f 69 64 d_broadcast(void
2d90: 20 2a 70 29 0a 7b 0a 09 6d 6f 6e 69 74 6f 72 5f *p).{..monitor_
2da0: 74 20 2a 20 6c 6f 63 6b 20 3d 20 74 68 72 65 61 t * lock = threa
2db0: 64 5f 6d 6f 6e 69 74 6f 72 5f 67 65 74 28 70 29 d_monitor_get(p)
2dc0: 3b 0a 0a 09 6d 6f 6e 69 74 6f 72 5f 62 72 6f 61 ;...monitor_broa
2dd0: 64 63 61 73 74 28 6c 6f 63 6b 29 3b 0a 7d 0a 0a dcast(lock);.}..
2de0: 76 6f 69 64 20 74 68 72 65 61 64 5f 77 61 69 74 void thread_wait
2df0: 28 76 6f 69 64 20 2a 70 29 0a 7b 0a 09 6d 6f 6e (void *p).{..mon
2e00: 69 74 6f 72 5f 74 20 2a 20 6c 6f 63 6b 20 3d 20 itor_t * lock =
2e10: 74 68 72 65 61 64 5f 6d 6f 6e 69 74 6f 72 5f 67 thread_monitor_g
2e20: 65 74 28 70 29 3b 0a 0a 09 6d 6f 6e 69 74 6f 72 et(p);...monitor
2e30: 5f 77 61 69 74 28 6c 6f 63 6b 29 3b 0a 7d 0a 23 _wait(lock);.}.#
2e40: 65 6e 64 69 66 0a 0a 73 74 61 74 69 63 20 76 6f endif..static vo
2e50: 69 64 20 73 79 6e 63 5f 64 65 61 64 6c 6f 63 6b id sync_deadlock
2e60: 5f 74 65 73 74 28 29 0a 7b 0a 09 73 74 61 74 69 _test().{..stati
2e70: 63 20 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 c interrupt_moni
2e80: 74 6f 72 5f 74 20 74 65 73 74 5b 32 5d 20 3d 20 tor_t test[2] =
2e90: 7b 30 7d 3b 0a 0a 09 74 68 72 65 61 64 5f 74 20 {0};...thread_t
2ea0: 2a 20 74 68 72 65 61 64 20 3d 20 74 68 72 65 61 * thread = threa
2eb0: 64 5f 66 6f 72 6b 28 29 3b 0a 09 69 66 20 28 74 d_fork();..if (t
2ec0: 68 72 65 61 64 29 20 7b 0a 09 09 49 4e 54 45 52 hread) {...INTER
2ed0: 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f 41 55 54 RUPT_MONITOR_AUT
2ee0: 4f 4c 4f 43 4b 28 74 65 73 74 29 20 7b 0a 09 09 OLOCK(test) {...
2ef0: 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 .interrupt_monit
2f00: 6f 72 5f 77 61 69 74 28 74 65 73 74 29 3b 0a 09 or_wait(test);..
2f10: 09 09 49 4e 54 45 52 52 55 50 54 5f 4d 4f 4e 49 ..INTERRUPT_MONI
2f20: 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 74 65 73 TOR_AUTOLOCK(tes
2f30: 74 2b 31 29 20 7b 0a 09 09 09 7d 0a 09 09 7d 0a t+1) {....}...}.
2f40: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 49 4e 54 45 .} else {...INTE
2f50: 52 52 55 50 54 5f 4d 4f 4e 49 54 4f 52 5f 41 55 RRUPT_MONITOR_AU
2f60: 54 4f 4c 4f 43 4b 28 74 65 73 74 2b 31 29 20 7b TOLOCK(test+1) {
2f70: 0a 09 09 09 49 4e 54 45 52 52 55 50 54 5f 4d 4f ....INTERRUPT_MO
2f80: 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 74 NITOR_AUTOLOCK(t
2f90: 65 73 74 29 20 7b 0a 09 09 09 09 69 6e 74 65 72 est) {.....inter
2fa0: 72 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 73 69 67 rupt_monitor_sig
2fb0: 6e 61 6c 28 74 65 73 74 29 3b 0a 09 09 09 09 74 nal(test);.....t
2fc0: 68 72 65 61 64 5f 79 69 65 6c 64 28 29 3b 0a 09 hread_yield();..
2fd0: 09 09 7d 0a 09 09 7d 0a 09 09 74 68 72 65 61 64 ..}...}...thread
2fe0: 5f 65 78 69 74 28 4e 55 4c 4c 29 3b 0a 09 7d 0a _exit(NULL);..}.
2ff0: 09 74 68 72 65 61 64 5f 6a 6f 69 6e 28 74 68 72 .thread_join(thr
3000: 65 61 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 ead);.}..static
3010: 76 6f 69 64 20 6d 6f 6e 69 74 6f 72 5f 74 65 73 void monitor_tes
3020: 74 28 29 0a 7b 0a 09 73 74 61 74 69 63 20 6d 6f t().{..static mo
3030: 6e 69 74 6f 72 5f 74 20 74 65 73 74 5b 31 5d 3b nitor_t test[1];
3040: 0a 09 73 74 61 74 69 63 20 69 6e 74 20 72 75 6e ..static int run
3050: 6e 69 6e 67 20 3d 20 31 3b 0a 09 69 6e 74 20 6e ning = 1;..int n
3060: 75 6d 20 3d 20 31 3b 0a 09 74 68 72 65 61 64 5f um = 1;..thread_
3070: 74 20 2a 20 74 68 72 65 61 64 20 3d 20 74 68 72 t * thread = thr
3080: 65 61 64 5f 66 6f 72 6b 28 29 3b 0a 09 69 66 20 ead_fork();..if
3090: 28 74 68 72 65 61 64 29 20 7b 0a 09 09 66 6f 72 (thread) {...for
30a0: 28 69 6e 74 20 69 3d 30 3b 20 69 3c 31 30 30 30 (int i=0; i<1000
30b0: 30 30 30 3b 20 69 2b 2b 29 20 7b 0a 09 09 09 4d 000; i++) {....M
30c0: 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 ONITOR_AUTOLOCK(
30d0: 74 65 73 74 29 20 7b 0a 09 09 09 09 6d 6f 6e 69 test) {.....moni
30e0: 74 6f 72 5f 73 69 67 6e 61 6c 28 74 65 73 74 29 tor_signal(test)
30f0: 3b 0a 09 09 09 7d 0a 09 09 09 74 68 72 65 61 64 ;....}....thread
3100: 5f 79 69 65 6c 64 28 29 3b 0a 09 09 7d 0a 09 09 _yield();...}...
3110: 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c 4f 43 4b MONITOR_AUTOLOCK
3120: 28 74 65 73 74 29 20 7b 0a 09 09 09 72 75 6e 6e (test) {....runn
3130: 69 6e 67 20 3d 20 30 3b 0a 09 09 09 6d 6f 6e 69 ing = 0;....moni
3140: 74 6f 72 5f 73 69 67 6e 61 6c 28 74 65 73 74 29 tor_signal(test)
3150: 3b 0a 09 09 7d 0a 09 09 74 68 72 65 61 64 5f 79 ;...}...thread_y
3160: 69 65 6c 64 28 29 3b 0a 09 09 74 68 72 65 61 64 ield();...thread
3170: 5f 6a 6f 69 6e 28 74 68 72 65 61 64 29 3b 0a 09 _join(thread);..
3180: 7d 20 65 6c 73 65 20 7b 0a 09 09 4d 4f 4e 49 54 } else {...MONIT
3190: 4f 52 5f 41 55 54 4f 4c 4f 43 4b 28 74 65 73 74 OR_AUTOLOCK(test
31a0: 29 20 7b 0a 09 09 09 77 68 69 6c 65 28 72 75 6e ) {....while(run
31b0: 6e 69 6e 67 29 20 7b 0a 09 09 09 09 6d 6f 6e 69 ning) {.....moni
31c0: 74 6f 72 5f 77 61 69 74 28 74 65 73 74 29 3b 0a tor_wait(test);.
31d0: 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 7d 0a 0a 76 ...}...}..}.}..v
31e0: 6f 69 64 20 73 79 6e 63 5f 74 65 73 74 28 29 0a oid sync_test().
31f0: 7b 0a 09 73 79 6e 63 5f 64 65 61 64 6c 6f 63 6b {..sync_deadlock
3200: 5f 74 65 73 74 28 29 3b 0a 09 6d 6f 6e 69 74 6f _test();..monito
3210: 72 5f 74 65 73 74 28 29 3b 0a 7d 0a r_test();.}.