comparison packages/kernel/current/src/sync/bin_sem.cxx @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
comparison
equal deleted inserted replaced
-1:000000000000 0:3111d98ba7b3
1 //==========================================================================
2 //
3 // sync/bin_sem.cxx
4 //
5 // Binary semaphore implementation
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
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //==========================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
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
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