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