|
0
|
1 //========================================================================== |
|
|
2 // |
|
2
|
3 // sync/bin_sem.cxx |
|
0
|
4 // |
|
2
|
5 // Binary semaphore implementation |
|
0
|
6 // |
|
|
7 //========================================================================== |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
2
|
25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
|
0
|
26 // ------------------------------------------- |
|
|
27 // |
|
|
28 //####COPYRIGHTEND#### |
|
|
29 //========================================================================== |
|
|
30 //#####DESCRIPTIONBEGIN#### |
|
|
31 // |
|
2
|
32 // Author(s): nickg |
|
|
33 // Contributors: nickg |
|
|
34 // Date: 1997-09-24 |
|
|
35 // Purpose: Cyg_Binary_Semaphore implementation |
|
|
36 // Description: This file contains the implementations of the binary semaphore |
|
0
|
37 // class. |
|
|
38 // |
|
|
39 //####DESCRIPTIONEND#### |
|
|
40 // |
|
|
41 //========================================================================== |
|
|
42 |
|
|
43 #include <pkgconf/kernel.h> |
|
|
44 |
|
|
45 #include <cyg/kernel/ktypes.h> // base kernel types |
|
|
46 #include <cyg/infra/cyg_trac.h> // tracing macros |
|
|
47 #include <cyg/infra/cyg_ass.h> // assertion macros |
|
|
48 #include <cyg/kernel/instrmnt.h> // instrumentation |
|
|
49 |
|
|
50 #include <cyg/kernel/thread.inl> // Cyg_Thread inlines |
|
|
51 |
|
|
52 #include <cyg/kernel/sema.hxx> // our header |
|
|
53 |
|
|
54 #include <cyg/kernel/sched.inl> // scheduler inlines |
|
|
55 |
|
|
56 // ------------------------------------------------------------------------- |
|
|
57 |
|
|
58 Cyg_Binary_Semaphore::Cyg_Binary_Semaphore ( |
|
|
59 cyg_bool init_state |
|
|
60 ) |
|
|
61 { |
|
|
62 state = init_state; |
|
|
63 } |
|
|
64 |
|
|
65 // ------------------------------------------------------------------------- |
|
|
66 |
|
|
67 Cyg_Binary_Semaphore::~Cyg_Binary_Semaphore ( ) |
|
|
68 { |
|
|
69 } |
|
|
70 |
|
|
71 // ------------------------------------------------------------------------- |
|
|
72 |
|
|
73 cyg_bool Cyg_Binary_Semaphore::wait() |
|
|
74 { |
|
|
75 cyg_bool result = true; |
|
|
76 Cyg_Thread *self = Cyg_Thread::self(); |
|
|
77 |
|
|
78 // Prevent preemption |
|
|
79 Cyg_Scheduler::lock(); |
|
|
80 |
|
|
81 CYG_INSTRUMENT_BINSEM( CLAIM, this, state ); |
|
|
82 |
|
|
83 while( !state && result ) |
|
|
84 { |
|
|
85 self->set_sleep_reason( Cyg_Thread::WAIT ); |
|
|
86 |
|
|
87 self->sleep(); |
|
|
88 |
|
|
89 queue.enqueue( self ); |
|
|
90 |
|
|
91 CYG_INSTRUMENT_BINSEM( WAIT, this, 0 ); |
|
|
92 |
|
|
93 CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1, "Called with non-zero scheduler lock"); |
|
|
94 |
|
|
95 Cyg_Scheduler::unlock(); |
|
|
96 Cyg_Scheduler::lock(); |
|
|
97 |
|
|
98 CYG_INSTRUMENT_BINSEM( WOKE, this, state ); |
|
|
99 |
|
|
100 switch( self->get_wake_reason() ) |
|
|
101 { |
|
|
102 case Cyg_Thread::DESTRUCT: |
|
|
103 case Cyg_Thread::BREAK: |
|
|
104 result = false; |
|
|
105 break; |
|
|
106 |
|
|
107 case Cyg_Thread::EXIT: |
|
|
108 self->exit(); |
|
|
109 break; |
|
|
110 |
|
|
111 default: |
|
|
112 break; |
|
|
113 } |
|
|
114 |
|
|
115 } |
|
|
116 |
|
|
117 if( result ) state = false; |
|
|
118 |
|
|
119 // Unlock the scheduler and maybe switch threads |
|
|
120 Cyg_Scheduler::unlock(); |
|
|
121 |
|
|
122 return result; |
|
|
123 } |
|
|
124 |
|
|
125 // ------------------------------------------------------------------------- |
|
|
126 |
|
|
127 cyg_bool Cyg_Binary_Semaphore::trywait() |
|
|
128 { |
|
|
129 cyg_bool result = true; |
|
|
130 |
|
|
131 // Prevent preemption |
|
|
132 Cyg_Scheduler::lock(); |
|
|
133 |
|
|
134 if( state ) state = false; |
|
|
135 else result = false; |
|
|
136 |
|
|
137 CYG_INSTRUMENT_BINSEM( TRY, this, result ); |
|
|
138 |
|
|
139 // Unlock the scheduler and maybe switch threads |
|
|
140 Cyg_Scheduler::unlock(); |
|
|
141 |
|
|
142 return result; |
|
|
143 } |
|
|
144 |
|
|
145 // ------------------------------------------------------------------------- |
|
|
146 |
|
|
147 void Cyg_Binary_Semaphore::post() |
|
|
148 { |
|
|
149 // Prevent preemption |
|
|
150 Cyg_Scheduler::lock(); |
|
|
151 |
|
|
152 CYG_INSTRUMENT_BINSEM( POST, this, 0 ); |
|
|
153 |
|
|
154 state = true; |
|
|
155 |
|
|
156 if( !queue.empty() ) { |
|
|
157 |
|
|
158 // The queue is non-empty, so grab the next |
|
|
159 // thread from it and wake it up. The waiter |
|
|
160 // will clear the flag. |
|
|
161 |
|
|
162 Cyg_Thread *thread = queue.dequeue(); |
|
|
163 |
|
|
164 thread->set_wake_reason( Cyg_Thread::DONE ); |
|
|
165 |
|
|
166 thread->wake(); |
|
|
167 |
|
|
168 CYG_INSTRUMENT_BINSEM( WAKE, this, thread ); |
|
|
169 } |
|
|
170 |
|
|
171 // Unlock the scheduler and maybe switch threads |
|
|
172 Cyg_Scheduler::unlock(); |
|
|
173 |
|
|
174 } |
|
|
175 |
|
|
176 // ------------------------------------------------------------------------- |
|
|
177 |
|
|
178 cyg_bool Cyg_Binary_Semaphore::posted() |
|
|
179 { |
|
|
180 // This is a single read of the value of state. |
|
|
181 // This is already atomic, hence there is no need |
|
|
182 // to lock the scheduler. |
|
|
183 |
|
|
184 return state; |
|
|
185 } |
|
|
186 |
|
|
187 // ------------------------------------------------------------------------- |
|
|
188 // EOF sync/bin_sem.cxx |