Mercurial > ecos
annotate packages/kernel/current/src/sync/mutex.cxx @ 3292:7f8e529b4d82 default tip
Fix FREESCALE_EDMA_NBYTES_MLOFFYES_MLOFF() so it works with negative offsets.
| author | vae |
|---|---|
| date | Wed, 29 Apr 2015 23:31:48 +0000 |
| parents | 74dbf4c3f2e1 |
| children |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // sync/mutex.cxx |
| 0 | 4 // |
| 2 | 5 // Mutex and condition variable implementation |
| 0 | 6 // |
| 7 //========================================================================== | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
8 // ####ECOSGPLCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
9 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
12 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
16 // version. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
17 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
21 // for more details. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
22 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
23 // You should have received a copy of the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
24 // along with eCos; if not, write to the Free Software Foundation, Inc., |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
26 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
27 // As a special exception, if other files instantiate templates or use |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
28 // macros or inline functions from this file, or you compile this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
29 // and link it with other works to produce a work based on this file, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
30 // this file does not by itself cause the resulting work to be covered by |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
31 // the GNU General Public License. However the source code for this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
32 // must still be made available in accordance with section (3) of the GNU |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
33 // General Public License v2. |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
34 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
35 // This exception does not invalidate any other reasons why a work based |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
36 // on this file might be covered by the GNU General Public License. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
37 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
210
diff
changeset
|
38 // ####ECOSGPLCOPYRIGHTEND#### |
| 0 | 39 //========================================================================== |
| 40 //#####DESCRIPTIONBEGIN#### | |
| 41 // | |
| 2 | 42 // Author(s): nickg |
| 43 // Contributors: nickg, jlarmour | |
| 44 // Date: 1999-02-17 | |
| 45 // Purpose: Mutex implementation | |
| 46 // Description: This file contains the implementations of the mutex | |
| 47 // and condition variable classes. | |
| 0 | 48 // |
| 49 //####DESCRIPTIONEND#### | |
| 50 // | |
| 51 //========================================================================== | |
| 52 | |
| 53 #include <pkgconf/kernel.h> | |
| 54 | |
| 55 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 56 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 57 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 58 #include <cyg/kernel/instrmnt.h> // instrumentation | |
| 59 | |
| 60 #include <cyg/kernel/mutex.hxx> // our header | |
| 61 | |
| 62 #include <cyg/kernel/thread.inl> // thread inlines | |
| 63 #include <cyg/kernel/sched.inl> // scheduler inlines | |
| 64 #include <cyg/kernel/clock.inl> // clock inlines | |
| 65 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
66 // ------------------------------------------------------------------------- |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
67 // Mutex protocol test macros. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
68 // If the dynamic protocol option is enabled, then these generate appropriate |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
69 // tests on the protocol field. If there is no dynamic choice then they simply |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
70 // result in empty statements. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
71 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
72 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
73 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
74 #define IF_PROTOCOL_INHERIT if( protocol == INHERIT ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
75 #define IF_PROTOCOL_CEILING if( protocol == CEILING ) |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
76 #define IF_PROTOCOL_ACTIVE if( protocol != NONE ) |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
77 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
78 #else |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
79 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
80 #define IF_PROTOCOL_INHERIT |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
81 #define IF_PROTOCOL_CEILING |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
82 #define IF_PROTOCOL_ACTIVE |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
83 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
84 #endif |
| 0 | 85 |
| 86 // ------------------------------------------------------------------------- | |
| 87 // Constructor | |
| 88 | |
| 89 Cyg_Mutex::Cyg_Mutex() | |
| 90 { | |
| 91 CYG_REPORT_FUNCTION(); | |
| 92 | |
| 93 locked = false; | |
| 94 owner = NULL; | |
| 2 | 95 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
96 #if defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT) && \ |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
97 defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
98 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
99 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_INHERIT |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
100 protocol = INHERIT; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
101 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
102 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
103 protocol = CEILING; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
104 ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
105 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
106 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_NONE |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
107 protocol = NONE; |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
108 #endif |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
109 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
110 #else // not (DYNAMIC and DEFAULT defined) |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
111 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
112 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
113 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
114 |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
115 // if there is a default priority ceiling defined, use that to initialize |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
116 // the ceiling. |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
117 ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY; |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
118 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
119 #else |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
120 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
121 // Otherwise set it to zero. |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
122 ceiling = 0; |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
123 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
124 #endif |
|
182
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
125 #endif |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
126 |
|
f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
jlarmour
parents:
181
diff
changeset
|
127 #endif // DYNAMIC and DEFAULT defined |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
128 |
| 2 | 129 CYG_REPORT_RETURN(); |
| 0 | 130 } |
| 131 | |
| 132 // ------------------------------------------------------------------------- | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
133 // Construct with defined protocol |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
134 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
135 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
136 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
137 Cyg_Mutex::Cyg_Mutex( cyg_protcol protocol_arg ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
138 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
139 CYG_REPORT_FUNCTION(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
140 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
141 locked = false; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
142 owner = NULL; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
143 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
144 protocol = protocol_arg; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
145 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
146 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
147 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
148 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
149 // if there is a default priority ceiling defined, use that to initialize |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
150 // the ceiling. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
151 ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
152 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
153 #else |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
154 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
155 // Otherwise set it to zero. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
156 ceiling = 0; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
157 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
158 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
159 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
160 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
161 CYG_REPORT_RETURN(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
162 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
163 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
164 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
165 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
166 // ------------------------------------------------------------------------- |
| 0 | 167 // Destructor |
| 168 | |
| 169 Cyg_Mutex::~Cyg_Mutex() | |
| 170 { | |
| 171 CYG_REPORT_FUNCTION(); | |
| 172 | |
| 173 CYG_ASSERT( owner == NULL, "Deleting mutex with owner"); | |
| 174 CYG_ASSERT( queue.empty(), "Deleting mutex with waiting threads"); | |
| 2 | 175 CYG_REPORT_RETURN(); |
| 0 | 176 } |
| 177 | |
| 178 // ------------------------------------------------------------------------- | |
| 179 | |
| 180 #ifdef CYGDBG_USE_ASSERTS | |
| 181 | |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
66
diff
changeset
|
182 cyg_bool |
| 2 | 183 Cyg_Mutex::check_this( cyg_assert_class_zeal zeal) const |
| 0 | 184 { |
| 185 // CYG_REPORT_FUNCTION(); | |
| 186 | |
| 187 // check that we have a non-NULL pointer first | |
| 188 if( this == NULL ) return false; | |
| 189 | |
| 190 switch( zeal ) | |
| 191 { | |
| 192 case cyg_system_test: | |
| 193 case cyg_extreme: | |
| 194 case cyg_thorough: | |
| 195 case cyg_quick: | |
| 196 case cyg_trivial: | |
| 197 if( locked && owner == NULL ) return false; | |
| 198 if( !locked && owner != NULL ) return false; | |
| 199 case cyg_none: | |
| 200 default: | |
| 201 break; | |
| 202 }; | |
| 203 | |
| 204 return true; | |
| 205 } | |
| 206 | |
| 207 #endif | |
| 208 | |
| 209 // ------------------------------------------------------------------------- | |
| 210 // Lock and/or wait | |
| 211 | |
| 2 | 212 cyg_bool |
| 213 Cyg_Mutex::lock(void) | |
| 0 | 214 { |
| 2 | 215 CYG_REPORT_FUNCTYPE("returning %d"); |
| 0 | 216 |
| 217 cyg_bool result = true; | |
| 218 Cyg_Thread *self = Cyg_Thread::self(); | |
| 219 | |
| 220 // Prevent preemption | |
| 221 Cyg_Scheduler::lock(); | |
| 222 | |
| 223 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 224 | |
| 225 CYG_INSTRUMENT_MUTEX(LOCK, this, 0); | |
| 226 | |
| 227 // Loop while the mutex is locked, sleeping each time around | |
| 228 // the loop. This copes with the possibility of a higher priority | |
| 229 // thread grabbing the mutex between the wakeup in unlock() and | |
| 230 // this thread actually starting. | |
| 231 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
232 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
233 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
234 IF_PROTOCOL_ACTIVE |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
235 self->count_mutex(); |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
236 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
237 #endif |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
238 |
|
181
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
239 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
240 |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
241 IF_PROTOCOL_CEILING |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
242 self->set_priority_ceiling(ceiling); |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
243 |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
244 #endif |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
245 |
| 2 | 246 while( locked && result ) |
| 0 | 247 { |
| 248 CYG_ASSERT( self != owner, "Locking mutex I already own"); | |
| 249 | |
| 250 self->set_sleep_reason( Cyg_Thread::WAIT ); | |
| 251 | |
| 252 self->sleep(); | |
| 253 | |
| 254 queue.enqueue( self ); | |
| 255 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
256 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT |
| 0 | 257 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
258 IF_PROTOCOL_INHERIT |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
259 owner->inherit_priority(self); |
|
28
18ee5a9c102e
Merge from eCos master repository on 1999-08-09-17:04:48-BST
jlarmour
parents:
2
diff
changeset
|
260 |
| 0 | 261 #endif |
| 262 | |
| 263 CYG_INSTRUMENT_MUTEX(WAIT, this, 0); | |
| 264 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
265 // Allow other threads to run |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
266 Cyg_Scheduler::reschedule(); |
| 0 | 267 |
| 268 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 269 | |
| 270 switch( self->get_wake_reason() ) | |
| 271 { | |
| 272 case Cyg_Thread::DESTRUCT: | |
| 273 case Cyg_Thread::BREAK: | |
| 274 result = false; | |
| 275 break; | |
| 276 | |
| 277 case Cyg_Thread::EXIT: | |
| 278 self->exit(); | |
| 279 break; | |
| 280 | |
| 281 default: | |
| 282 break; | |
| 283 } | |
| 284 | |
| 285 } | |
| 286 | |
| 287 if( result ) | |
| 288 { | |
| 289 locked = true; | |
| 290 owner = self; | |
| 291 | |
|
181
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
292 CYG_INSTRUMENT_MUTEX(LOCKED, this, 0); |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
293 } |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
294 else |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
295 { |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
296 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
297 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
298 IF_PROTOCOL_ACTIVE |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
299 self->uncount_mutex(); |
|
181
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
300 |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
301 #endif |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
302 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
303 |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
304 IF_PROTOCOL_INHERIT |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
305 self->disinherit_priority(); |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
306 |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
307 #endif |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
308 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
309 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
310 IF_PROTOCOL_CEILING |
|
181
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
311 self->clear_priority_ceiling(); |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
312 |
|
d61da071934c
Merge from eCos master repository on 2001-08-22-06:38:55-BST
jlarmour
parents:
177
diff
changeset
|
313 #endif |
| 0 | 314 } |
| 315 | |
| 316 // Unlock the scheduler and maybe switch threads | |
| 317 Cyg_Scheduler::unlock(); | |
| 318 | |
| 319 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 320 | |
| 2 | 321 CYG_REPORT_RETVAL(result); |
| 322 | |
| 0 | 323 return result; |
| 324 } | |
| 325 | |
| 326 // ------------------------------------------------------------------------- | |
| 327 // Try to lock and return success | |
| 328 | |
| 2 | 329 cyg_bool |
| 330 Cyg_Mutex::trylock(void) | |
| 0 | 331 { |
| 2 | 332 CYG_REPORT_FUNCTYPE("returning %d"); |
| 0 | 333 |
| 334 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 335 | |
| 336 cyg_bool result = true; | |
| 337 | |
| 338 // Prevent preemption | |
| 339 Cyg_Scheduler::lock(); | |
| 340 | |
| 341 // If the mutex is not locked, grab it | |
| 342 // for ourself. Otherwise return failure. | |
| 343 if( !locked ) | |
| 344 { | |
| 345 Cyg_Thread *self = Cyg_Thread::self(); | |
| 346 | |
| 347 locked = true; | |
| 348 owner = self; | |
| 349 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
350 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL |
| 0 | 351 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
352 IF_PROTOCOL_ACTIVE |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
353 self->count_mutex(); |
| 0 | 354 |
| 355 #endif | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
356 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
357 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
358 IF_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
359 self->set_priority_ceiling(ceiling); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
360 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
361 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
362 |
| 0 | 363 } |
| 364 else result = false; | |
| 365 | |
| 366 CYG_INSTRUMENT_MUTEX(TRY, this, result); | |
| 367 | |
| 368 // Unlock the scheduler and maybe switch threads | |
| 369 Cyg_Scheduler::unlock(); | |
| 370 | |
| 2 | 371 CYG_REPORT_RETVAL(result); |
| 0 | 372 return result; |
| 373 } | |
| 374 | |
| 375 // ------------------------------------------------------------------------- | |
| 376 // unlock | |
| 377 | |
| 2 | 378 void |
| 379 Cyg_Mutex::unlock(void) | |
| 0 | 380 { |
| 381 CYG_REPORT_FUNCTION(); | |
| 382 | |
| 383 // Prevent preemption | |
| 384 Cyg_Scheduler::lock(); | |
| 385 | |
| 386 CYG_INSTRUMENT_MUTEX(UNLOCK, this, 0); | |
| 387 | |
| 388 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 389 CYG_ASSERT( locked, "Unlock mutex that is not locked"); | |
| 390 CYG_ASSERT( owner == Cyg_Thread::self(), "Unlock mutex I do not own"); | |
| 391 | |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
392 if( !queue.empty() ) { |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
393 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
394 // The queue is non-empty, so grab the next |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
395 // thread from it and wake it up. |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
396 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
397 Cyg_Thread *thread = queue.dequeue(); |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
398 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
399 CYG_ASSERTCLASS( thread, "Bad thread pointer"); |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
400 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
401 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
402 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
403 // Give the owner-to-be a chance to inherit from the remaining |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
404 // queue or the relinquishing thread: |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
405 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
406 IF_PROTOCOL_INHERIT |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
407 thread->relay_priority(owner, &queue); |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
408 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
409 #endif |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
410 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
411 thread->set_wake_reason( Cyg_Thread::DONE ); |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
412 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
413 thread->wake(); |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
414 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
415 CYG_INSTRUMENT_MUTEX(WAKE, this, thread); |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
416 |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
417 } |
|
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
28
diff
changeset
|
418 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
419 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL |
| 0 | 420 |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
421 IF_PROTOCOL_ACTIVE |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
182
diff
changeset
|
422 owner->uncount_mutex(); |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
423 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
424 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
425 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
426 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
427 IF_PROTOCOL_INHERIT |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
428 owner->disinherit_priority(); |
| 0 | 429 |
| 430 #endif | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
431 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
432 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
433 IF_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
434 owner->clear_priority_ceiling(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
435 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
436 #endif |
| 0 | 437 |
| 438 locked = false; | |
| 439 owner = NULL; | |
| 440 | |
| 441 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 442 | |
| 443 // Unlock the scheduler and maybe switch threads | |
| 444 Cyg_Scheduler::unlock(); | |
| 445 | |
| 2 | 446 CYG_REPORT_RETURN(); |
| 447 } | |
| 448 | |
| 449 // ------------------------------------------------------------------------- | |
| 450 // Release all waiting threads. | |
| 451 | |
| 452 void Cyg_Mutex::release() | |
| 453 { | |
| 454 CYG_REPORT_FUNCTION(); | |
| 455 | |
| 456 // Prevent preemption | |
| 457 Cyg_Scheduler::lock(); | |
| 458 | |
| 459 CYG_INSTRUMENT_MUTEX(RELEASE, this, 0); | |
| 460 | |
| 461 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 462 | |
| 463 while( !queue.empty() ) | |
| 464 { | |
| 465 // The queue is non-empty, so grab each | |
| 466 // thread from it and release it. | |
| 467 | |
| 468 Cyg_Thread *thread = queue.dequeue(); | |
| 469 | |
| 470 CYG_ASSERTCLASS( thread, "Bad thread pointer"); | |
| 471 | |
| 472 thread->release(); | |
| 473 | |
| 474 CYG_INSTRUMENT_MUTEX(RELEASED, this, thread); | |
| 475 | |
| 476 } | |
| 477 | |
| 478 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 479 | |
| 480 // Unlock the scheduler and maybe switch threads | |
| 481 Cyg_Scheduler::unlock(); | |
| 482 | |
| 483 CYG_REPORT_RETURN(); | |
| 0 | 484 } |
| 485 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
486 // ------------------------------------------------------------------------- |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
487 // Set ceiling priority for priority ceiling protocol |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
488 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
489 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
490 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
491 void Cyg_Mutex::set_ceiling( cyg_priority priority ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
492 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
493 CYG_REPORT_FUNCTION(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
494 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
495 // CYG_ASSERT( priority >= CYG_THREAD_MAX_PRIORITY, "Priority out of range"); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
496 // CYG_ASSERT( priority <= CYG_THREAD_MIN_PRIORITY, "Priority out of range"); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
497 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
498 // Prevent preemption |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
499 Cyg_Scheduler::lock(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
500 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
501 ceiling = priority; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
502 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
503 // Unlock the scheduler |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
504 Cyg_Scheduler::unlock(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
505 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
506 CYG_REPORT_RETURN(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
507 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
508 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
509 #endif |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
510 |
|
177
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
511 // ------------------------------------------------------------------------- |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
512 // Set priority inversion protocol |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
513 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
514 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
515 void Cyg_Mutex::set_protocol( cyg_protcol new_protocol ) |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
516 { |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
517 CYG_REPORT_FUNCTION(); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
518 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
519 // Prevent preemption |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
520 Cyg_Scheduler::lock(); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
521 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
522 protocol = new_protocol; |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
523 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
524 // Unlock the scheduler |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
525 Cyg_Scheduler::unlock(); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
526 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
527 CYG_REPORT_RETURN(); |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
528 } |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
529 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
530 #endif |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
531 |
|
4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
jlarmour
parents:
124
diff
changeset
|
532 |
| 0 | 533 //========================================================================== |
| 534 // Condition variables | |
| 535 | |
| 536 Cyg_Condition_Variable::Cyg_Condition_Variable( | |
| 537 Cyg_Mutex &mx // linked mutex | |
| 538 ) | |
| 539 { | |
| 540 CYG_REPORT_FUNCTION(); | |
| 541 | |
| 542 mutex = &mx; | |
| 543 | |
| 544 CYG_ASSERTCLASS( mutex, "Invalid mutex argument"); | |
| 2 | 545 |
| 546 CYG_REPORT_RETURN(); | |
| 0 | 547 } |
| 548 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
549 Cyg_Condition_Variable::Cyg_Condition_Variable() |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
550 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
551 CYG_REPORT_FUNCTION(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
552 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
553 mutex = NULL; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
554 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
555 CYG_REPORT_RETURN(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
556 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
557 |
| 0 | 558 // ------------------------------------------------------------------------- |
| 559 // Destructor | |
| 560 | |
| 561 Cyg_Condition_Variable::~Cyg_Condition_Variable() | |
| 562 { | |
| 563 CYG_REPORT_FUNCTION(); | |
| 564 | |
| 565 CYG_ASSERT( queue.empty(), "Deleting condvar with waiting threads"); | |
| 2 | 566 |
| 567 CYG_REPORT_RETURN(); | |
| 0 | 568 } |
| 569 | |
| 570 // ------------------------------------------------------------------------- | |
| 571 | |
| 572 #ifdef CYGDBG_USE_ASSERTS | |
| 573 | |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
66
diff
changeset
|
574 cyg_bool |
| 2 | 575 Cyg_Condition_Variable::check_this( cyg_assert_class_zeal zeal) const |
| 0 | 576 { |
| 2 | 577 bool result = true; |
| 578 | |
| 579 CYG_REPORT_FUNCTYPE("returning %d"); | |
| 580 CYG_REPORT_FUNCARG1("zeal = %d", zeal); | |
| 0 | 581 |
| 582 // check that we have a non-NULL pointer first | |
| 2 | 583 if( this == NULL ) |
| 584 result = false; | |
| 585 else { | |
| 586 | |
| 587 switch( zeal ) | |
| 588 { | |
| 589 case cyg_system_test: | |
| 590 case cyg_extreme: | |
| 591 case cyg_thorough: | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
592 if( mutex != NULL && !mutex->check_this(zeal) ) |
| 2 | 593 result = false; |
| 594 case cyg_quick: | |
| 595 case cyg_trivial: | |
| 596 case cyg_none: | |
| 597 default: | |
| 598 break; | |
| 599 } | |
| 600 } | |
| 0 | 601 |
| 2 | 602 CYG_REPORT_RETVAL(result); |
| 603 return result; | |
| 0 | 604 } |
| 605 | |
| 606 #endif | |
| 607 | |
| 608 // ------------------------------------------------------------------------- | |
| 609 // Wait for condition to be true | |
| 2 | 610 // Note: if this function is entered with the scheduler locked (e.g. to |
| 611 // suspend DSR processing) then there is no need to take the lock. Also | |
| 612 // in this case, exit with the scheduler locked, which allows this function | |
| 613 // to be used in a totally thread-safe manner. | |
| 0 | 614 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
615 cyg_bool |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
616 Cyg_Condition_Variable::wait_inner( Cyg_Mutex *mx ) |
| 0 | 617 { |
| 618 CYG_REPORT_FUNCTION(); | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
619 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
620 cyg_bool result = true; |
| 0 | 621 Cyg_Thread *self = Cyg_Thread::self(); |
| 622 | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
623 Cyg_Scheduler::lock(); |
| 0 | 624 |
| 625 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
626 CYG_ASSERTCLASS( mx, "Corrupt mutex"); |
| 0 | 627 CYG_ASSERTCLASS( self, "Bad self thread"); |
| 628 | |
| 629 CYG_INSTRUMENT_CONDVAR(WAIT, this, 0); | |
| 630 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
631 mx->unlock(); |
| 0 | 632 |
| 633 self->set_sleep_reason( Cyg_Thread::WAIT ); | |
| 634 | |
| 635 self->sleep(); | |
| 636 | |
| 637 queue.enqueue( self ); | |
| 638 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
639 // Avoid calling ASRs during the following unlock. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
640 self->set_asr_inhibit(); |
| 0 | 641 |
| 642 // Unlock the scheduler and switch threads | |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
643 Cyg_Scheduler::unlock_reschedule(); |
| 0 | 644 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
645 // Allow ASRs again |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
646 self->clear_asr_inhibit(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
647 |
| 0 | 648 CYG_INSTRUMENT_CONDVAR(WOKE, this, self->get_wake_reason()); |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
649 |
| 0 | 650 CYG_ASSERTCLASS( this, "Bad this pointer"); |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
651 CYG_ASSERTCLASS( mx, "Corrupt mutex"); |
| 0 | 652 |
| 653 switch( self->get_wake_reason() ) | |
| 654 { | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
655 case Cyg_Thread::DESTRUCT: // which, the cv or the mutex? |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
656 case Cyg_Thread::BREAK: |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
657 result = false; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
658 break; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
659 |
| 0 | 660 case Cyg_Thread::EXIT: |
| 661 self->exit(); | |
| 662 break; | |
| 663 | |
| 664 default: | |
| 665 break; | |
| 666 } | |
| 667 | |
| 668 // When we awake, we must re-acquire the mutex. Note that while | |
| 669 // it is essential to release the mutex and queue on the CV | |
| 670 // atomically relative to other threads, to avoid races, it is not | |
| 671 // necessary for us to re-acquire the mutex in the same atomic | |
| 672 // action. Hence we can do it after unlocking the scheduler. | |
| 2 | 673 // We need to loop here in case the thread is released while waiting |
| 674 // for the mutex. It is essential that we exit this function with the | |
| 675 // mutex claimed. | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
676 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
677 while ( !mx->lock() ) |
| 2 | 678 continue; |
| 0 | 679 |
| 680 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
681 CYG_ASSERTCLASS( mx, "Corrupt mutex"); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
682 CYG_ASSERT( mx->owner == self, "Not mutex owner"); |
| 2 | 683 |
| 684 CYG_REPORT_RETURN(); | |
| 685 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
686 return result; |
| 0 | 687 } |
| 688 | |
| 689 // ------------------------------------------------------------------------- | |
| 690 // Wake one thread | |
| 691 | |
| 2 | 692 void |
| 693 Cyg_Condition_Variable::signal(void) | |
| 0 | 694 { |
| 695 CYG_REPORT_FUNCTION(); | |
| 696 | |
| 697 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 698 | |
| 699 // Prevent preemption | |
| 700 Cyg_Scheduler::lock(); | |
| 701 | |
| 702 CYG_INSTRUMENT_CONDVAR(SIGNAL, this, 0); | |
| 703 | |
| 704 if( !queue.empty() ) | |
| 705 { | |
| 706 // The queue is non-empty, so grab the next | |
| 707 // thread from it and wake it up. | |
| 708 | |
| 709 Cyg_Thread *thread = queue.dequeue(); | |
| 710 | |
| 711 CYG_ASSERTCLASS( thread, "Bad thread pointer"); | |
| 712 | |
| 713 thread->set_wake_reason( Cyg_Thread::DONE ); | |
| 714 | |
| 715 thread->wake(); | |
| 716 | |
| 717 CYG_INSTRUMENT_CONDVAR(WAKE, this, thread); | |
| 718 | |
| 719 } | |
| 720 | |
| 721 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 722 | |
| 723 // Unlock the scheduler and maybe switch threads | |
| 724 Cyg_Scheduler::unlock(); | |
| 725 | |
| 2 | 726 CYG_REPORT_RETURN(); |
| 0 | 727 } |
| 728 | |
| 729 // ------------------------------------------------------------------------- | |
| 730 // Set cond true, wake all threads | |
| 731 | |
| 2 | 732 void |
| 733 Cyg_Condition_Variable::broadcast(void) | |
| 0 | 734 { |
| 735 CYG_REPORT_FUNCTION(); | |
| 736 | |
| 737 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 738 | |
| 739 // Prevent preemption | |
| 740 Cyg_Scheduler::lock(); | |
| 741 | |
| 742 CYG_INSTRUMENT_CONDVAR(BROADCAST, this, 0); | |
| 743 | |
| 744 // Grab all the threads from the queue and let them | |
| 745 // go. | |
| 746 | |
| 747 while( !queue.empty() ) | |
| 748 { | |
| 749 Cyg_Thread *thread = queue.dequeue(); | |
| 750 | |
| 751 CYG_ASSERTCLASS( thread, "Bad thread pointer"); | |
| 752 | |
| 753 thread->set_wake_reason( Cyg_Thread::DONE ); | |
| 754 | |
| 755 thread->wake(); | |
| 756 | |
| 757 CYG_INSTRUMENT_CONDVAR(WAKE, this, thread); | |
| 758 } | |
| 759 | |
| 760 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
| 761 | |
| 762 // Unlock the scheduler and maybe switch threads | |
| 763 Cyg_Scheduler::unlock(); | |
| 2 | 764 |
| 765 CYG_REPORT_RETURN(); | |
| 0 | 766 } |
| 767 | |
| 768 // ------------------------------------------------------------------------- | |
| 769 // Optional timed wait on a CV | |
| 770 | |
| 2 | 771 #if defined(CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT) |
| 0 | 772 |
| 2 | 773 cyg_bool |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
774 Cyg_Condition_Variable::wait_inner( Cyg_Mutex *mx, cyg_tick_count timeout ) |
| 0 | 775 { |
| 2 | 776 CYG_REPORT_FUNCTYPE("returning %d"); |
| 777 CYG_REPORT_FUNCARG1("timeout = %d", timeout); | |
| 0 | 778 |
| 779 CYG_ASSERTCLASS( this, "Bad this pointer"); | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
780 CYG_ASSERTCLASS( mx, "Corrupt mutex"); |
| 0 | 781 |
| 782 cyg_bool result = true; | |
| 783 | |
| 784 Cyg_Thread *self = Cyg_Thread::self(); | |
| 785 | |
| 786 CYG_ASSERTCLASS( self, "Bad self thread"); | |
| 787 | |
| 788 // Prevent preemption | |
| 789 Cyg_Scheduler::lock(); | |
| 790 | |
| 791 CYG_INSTRUMENT_CONDVAR(TIMED_WAIT, this, 0 ); | |
| 792 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
793 mx->unlock(); |
| 0 | 794 |
| 795 // The ordering of sleep() and set_timer() here are | |
| 796 // important. If the timeout is in the past, the thread | |
| 797 // will be woken up immediately and will not sleep. | |
| 798 | |
| 799 self->sleep(); | |
| 800 | |
| 801 // Set the timer and sleep reason | |
| 802 self->set_timer( timeout, Cyg_Thread::TIMEOUT ); | |
| 803 | |
| 804 // Only enqueue if the timeout has not already fired. | |
| 805 if( self->get_wake_reason() == Cyg_Thread::NONE ) | |
| 806 queue.enqueue( self ); | |
| 807 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
808 // Avoid calling ASRs during the following unlock. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
809 self->set_asr_inhibit(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
810 |
| 0 | 811 // Unlock the scheduler and switch threads |
|
124
0ec04793409a
Merge from eCos master repository on 2000-09-11-03:00:13-BST
jlarmour
parents:
115
diff
changeset
|
812 Cyg_Scheduler::unlock_reschedule(); |
| 0 | 813 |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
814 // Allow ASRs again |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
815 self->clear_asr_inhibit(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
816 |
| 0 | 817 CYG_ASSERTCLASS( this, "Bad this pointer"); |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
818 CYG_ASSERTCLASS( mx, "Corrupt mutex"); |
| 0 | 819 |
| 820 self->clear_timer(); | |
| 821 | |
| 822 CYG_INSTRUMENT_CONDVAR(WOKE, this, self->get_wake_reason()); | |
| 823 | |
| 824 switch( self->get_wake_reason() ) | |
| 825 { | |
| 826 case Cyg_Thread::TIMEOUT: | |
| 827 case Cyg_Thread::DESTRUCT: // which, the cv or the mutex? | |
| 828 case Cyg_Thread::BREAK: | |
| 829 result = false; | |
| 830 break; | |
| 831 | |
| 832 case Cyg_Thread::EXIT: | |
| 833 self->exit(); | |
| 834 break; | |
| 835 | |
| 836 default: | |
| 837 break; | |
| 838 } | |
| 839 | |
| 840 | |
| 841 // When we awake, we must re-acquire the mutex. Note that while | |
| 842 // it is essential to release the mutex and queue on the CV | |
| 843 // atomically relative to other threads, to avoid races, it is not | |
| 844 // necessary for us to re-acquire the mutex in the same atomic | |
| 845 // action. Hence we can do it after unlocking the scheduler. | |
| 846 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
847 while ( !mx->lock() ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
848 continue; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
849 |
| 0 | 850 CYG_ASSERTCLASS( this, "Bad this pointer"); |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
851 CYG_ASSERTCLASS( mx, "Corrupt mutex"); |
| 2 | 852 |
| 853 CYG_REPORT_RETVAL(result); | |
| 0 | 854 |
| 855 return result; | |
| 856 } | |
| 857 | |
| 858 #endif | |
| 859 | |
| 860 | |
| 861 // ------------------------------------------------------------------------- | |
| 862 // EOF sync/mutex.cxx |
