User | Revision | Line number | New contents of line |
segundo |
0:d7810ff946c1
|
1
|
//******************************************************************************
|
segundo |
0:d7810ff946c1
|
2
|
//*
|
segundo |
0:d7810ff946c1
|
3
|
//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System
|
segundo |
0:d7810ff946c1
|
4
|
//*
|
segundo |
0:d7810ff946c1
|
5
|
//* NICKNAME: scmRTOS
|
segundo |
0:d7810ff946c1
|
6
|
//*
|
segundo |
0:d7810ff946c1
|
7
|
//* PURPOSE: OS Services Header. Declarations And Definitions
|
segundo |
0:d7810ff946c1
|
8
|
//*
|
segundo |
0:d7810ff946c1
|
9
|
//* Version: 3.10
|
segundo |
0:d7810ff946c1
|
10
|
//*
|
segundo |
0:d7810ff946c1
|
11
|
//* $Revision: 256 $
|
segundo |
0:d7810ff946c1
|
12
|
//* $Date:: 2010-01-22 #$
|
segundo |
0:d7810ff946c1
|
13
|
//*
|
segundo |
0:d7810ff946c1
|
14
|
//* Copyright (c) 2003-2010, Harry E. Zhurov
|
segundo |
0:d7810ff946c1
|
15
|
//*
|
segundo |
0:d7810ff946c1
|
16
|
//* Permission is hereby granted, free of charge, to any person
|
segundo |
0:d7810ff946c1
|
17
|
//* obtaining a copy of this software and associated documentation
|
segundo |
0:d7810ff946c1
|
18
|
//* files (the "Software"), to deal in the Software without restriction,
|
segundo |
0:d7810ff946c1
|
19
|
//* including without limitation the rights to use, copy, modify, merge,
|
segundo |
0:d7810ff946c1
|
20
|
//* publish, distribute, sublicense, and/or sell copies of the Software,
|
segundo |
0:d7810ff946c1
|
21
|
//* and to permit persons to whom the Software is furnished to do so,
|
segundo |
0:d7810ff946c1
|
22
|
//* subject to the following conditions:
|
segundo |
0:d7810ff946c1
|
23
|
//*
|
segundo |
0:d7810ff946c1
|
24
|
//* The above copyright notice and this permission notice shall be included
|
segundo |
0:d7810ff946c1
|
25
|
//* in all copies or substantial portions of the Software.
|
segundo |
0:d7810ff946c1
|
26
|
//*
|
segundo |
0:d7810ff946c1
|
27
|
//* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
segundo |
0:d7810ff946c1
|
28
|
//* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
segundo |
0:d7810ff946c1
|
29
|
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
segundo |
0:d7810ff946c1
|
30
|
//* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
segundo |
0:d7810ff946c1
|
31
|
//* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
segundo |
0:d7810ff946c1
|
32
|
//* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
segundo |
0:d7810ff946c1
|
33
|
//* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
segundo |
0:d7810ff946c1
|
34
|
//*
|
segundo |
0:d7810ff946c1
|
35
|
//* =================================================================
|
segundo |
0:d7810ff946c1
|
36
|
//* See http://scmrtos.sourceforge.net for documentation, latest
|
segundo |
0:d7810ff946c1
|
37
|
//* information, license and contact details.
|
segundo |
0:d7810ff946c1
|
38
|
//* =================================================================
|
segundo |
0:d7810ff946c1
|
39
|
//*
|
segundo |
0:d7810ff946c1
|
40
|
//******************************************************************************
|
segundo |
0:d7810ff946c1
|
41
|
|
segundo |
0:d7810ff946c1
|
42
|
#ifndef OS_SERVICES_H
|
segundo |
0:d7810ff946c1
|
43
|
#define OS_SERVICES_H
|
segundo |
0:d7810ff946c1
|
44
|
|
segundo |
0:d7810ff946c1
|
45
|
namespace OS
|
segundo |
0:d7810ff946c1
|
46
|
{
|
segundo |
0:d7810ff946c1
|
47
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
48
|
//
|
segundo |
0:d7810ff946c1
|
49
|
// NAME : Mutex
|
segundo |
0:d7810ff946c1
|
50
|
//
|
segundo |
0:d7810ff946c1
|
51
|
/// Binary semaphore for support of mutual exclusion
|
segundo |
0:d7810ff946c1
|
52
|
//
|
segundo |
0:d7810ff946c1
|
53
|
// DESCRIPTION:
|
segundo |
0:d7810ff946c1
|
54
|
//
|
segundo |
0:d7810ff946c1
|
55
|
//
|
segundo |
0:d7810ff946c1
|
56
|
class TMutex
|
segundo |
0:d7810ff946c1
|
57
|
{
|
segundo |
0:d7810ff946c1
|
58
|
public:
|
segundo |
0:d7810ff946c1
|
59
|
INLINE TMutex() : ProcessMap(0), ValueTag(0) { }
|
segundo |
0:d7810ff946c1
|
60
|
void Lock();
|
segundo |
0:d7810ff946c1
|
61
|
void Unlock();
|
segundo |
0:d7810ff946c1
|
62
|
void UnlockISR();
|
segundo |
0:d7810ff946c1
|
63
|
|
segundo |
0:d7810ff946c1
|
64
|
INLINE bool LockSoftly() { TCritSect cs; if(ValueTag) return false; else Lock(); return true; }
|
segundo |
0:d7810ff946c1
|
65
|
INLINE bool IsLocked() const { TCritSect cs; if(ValueTag) return true; else return false; }
|
segundo |
0:d7810ff946c1
|
66
|
|
segundo |
0:d7810ff946c1
|
67
|
private:
|
segundo |
0:d7810ff946c1
|
68
|
TProcessMap ProcessMap;
|
segundo |
0:d7810ff946c1
|
69
|
TProcessMap ValueTag;
|
segundo |
0:d7810ff946c1
|
70
|
|
segundo |
0:d7810ff946c1
|
71
|
};
|
segundo |
0:d7810ff946c1
|
72
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
73
|
|
segundo |
0:d7810ff946c1
|
74
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
75
|
//
|
segundo |
0:d7810ff946c1
|
76
|
/// Event Flag
|
segundo |
0:d7810ff946c1
|
77
|
///
|
segundo |
0:d7810ff946c1
|
78
|
/// Intended for processes synchronization and
|
segundo |
0:d7810ff946c1
|
79
|
/// event notification one (or more) process by another
|
segundo |
0:d7810ff946c1
|
80
|
//
|
segundo |
0:d7810ff946c1
|
81
|
// DESCRIPTION:
|
segundo |
0:d7810ff946c1
|
82
|
//
|
segundo |
0:d7810ff946c1
|
83
|
//
|
segundo |
0:d7810ff946c1
|
84
|
class TEventFlag
|
segundo |
0:d7810ff946c1
|
85
|
{
|
segundo |
0:d7810ff946c1
|
86
|
public:
|
segundo |
0:d7810ff946c1
|
87
|
enum TValue { efOn = 1, efOff= 0 }; // prefix 'ef' means: "Event Flag"
|
segundo |
0:d7810ff946c1
|
88
|
|
segundo |
0:d7810ff946c1
|
89
|
public:
|
segundo |
0:d7810ff946c1
|
90
|
INLINE TEventFlag(TValue init_val = efOff) : ProcessMap(0), Value(init_val) { }
|
segundo |
0:d7810ff946c1
|
91
|
|
segundo |
0:d7810ff946c1
|
92
|
bool Wait(TTimeout timeout = 0);
|
segundo |
0:d7810ff946c1
|
93
|
void Signal();
|
segundo |
0:d7810ff946c1
|
94
|
INLINE void Clear() { TCritSect cs; Value = efOff; }
|
segundo |
0:d7810ff946c1
|
95
|
INLINE inline void SignalISR();
|
segundo |
0:d7810ff946c1
|
96
|
INLINE bool IsSignaled() { TCritSect cs; if(Value == efOn) return true; else return false; }
|
segundo |
0:d7810ff946c1
|
97
|
|
segundo |
0:d7810ff946c1
|
98
|
private:
|
segundo |
0:d7810ff946c1
|
99
|
TProcessMap ProcessMap;
|
segundo |
0:d7810ff946c1
|
100
|
TValue Value;
|
segundo |
0:d7810ff946c1
|
101
|
};
|
segundo |
0:d7810ff946c1
|
102
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
103
|
|
segundo |
0:d7810ff946c1
|
104
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
105
|
//
|
segundo |
0:d7810ff946c1
|
106
|
/// TChannel
|
segundo |
0:d7810ff946c1
|
107
|
///
|
segundo |
0:d7810ff946c1
|
108
|
/// Byte-wide data channel for transferring "raw" data
|
segundo |
0:d7810ff946c1
|
109
|
//
|
segundo |
0:d7810ff946c1
|
110
|
// DESCRIPTION:
|
segundo |
0:d7810ff946c1
|
111
|
//
|
segundo |
0:d7810ff946c1
|
112
|
//
|
segundo |
0:d7810ff946c1
|
113
|
class TChannel
|
segundo |
0:d7810ff946c1
|
114
|
{
|
segundo |
0:d7810ff946c1
|
115
|
public:
|
segundo |
0:d7810ff946c1
|
116
|
INLINE TChannel(byte* buf, byte size) : Cbuf(buf, size) { }
|
segundo |
0:d7810ff946c1
|
117
|
void Push(byte x);
|
segundo |
0:d7810ff946c1
|
118
|
byte Pop();
|
segundo |
0:d7810ff946c1
|
119
|
void Write(const byte* data, const byte count);
|
segundo |
0:d7810ff946c1
|
120
|
void Read(byte* const data, const byte count);
|
segundo |
0:d7810ff946c1
|
121
|
|
segundo |
0:d7810ff946c1
|
122
|
INLINE byte GetCount() const { TCritSect cs; return Cbuf.get_count(); }
|
segundo |
0:d7810ff946c1
|
123
|
|
segundo |
0:d7810ff946c1
|
124
|
private:
|
segundo |
0:d7810ff946c1
|
125
|
TProcessMap ProducersProcessMap;
|
segundo |
0:d7810ff946c1
|
126
|
TProcessMap ConsumersProcessMap;
|
segundo |
0:d7810ff946c1
|
127
|
usr::TCbuf Cbuf;
|
segundo |
0:d7810ff946c1
|
128
|
|
segundo |
0:d7810ff946c1
|
129
|
private:
|
segundo |
0:d7810ff946c1
|
130
|
void CheckWaiters(TProcessMap& pm);
|
segundo |
0:d7810ff946c1
|
131
|
};
|
segundo |
0:d7810ff946c1
|
132
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
133
|
|
segundo |
0:d7810ff946c1
|
134
|
|
segundo |
0:d7810ff946c1
|
135
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
136
|
//
|
segundo |
0:d7810ff946c1
|
137
|
// NAME : channel
|
segundo |
0:d7810ff946c1
|
138
|
//
|
segundo |
0:d7810ff946c1
|
139
|
// PURPOSE : Data channel for transferring data
|
segundo |
0:d7810ff946c1
|
140
|
// objects of arbitrary type
|
segundo |
0:d7810ff946c1
|
141
|
//
|
segundo |
0:d7810ff946c1
|
142
|
// DESCRIPTION:
|
segundo |
0:d7810ff946c1
|
143
|
//
|
segundo |
0:d7810ff946c1
|
144
|
//
|
segundo |
0:d7810ff946c1
|
145
|
template<typename T, word Size, typename S = byte>
|
segundo |
0:d7810ff946c1
|
146
|
/// channel
|
segundo |
0:d7810ff946c1
|
147
|
///
|
segundo |
0:d7810ff946c1
|
148
|
/// Data channel for transferring data objects of arbitrary type
|
segundo |
0:d7810ff946c1
|
149
|
class channel
|
segundo |
0:d7810ff946c1
|
150
|
{
|
segundo |
0:d7810ff946c1
|
151
|
public:
|
segundo |
0:d7810ff946c1
|
152
|
INLINE channel() : ProducersProcessMap(0)
|
segundo |
0:d7810ff946c1
|
153
|
, ConsumersProcessMap(0)
|
segundo |
0:d7810ff946c1
|
154
|
, pool()
|
segundo |
0:d7810ff946c1
|
155
|
{
|
segundo |
0:d7810ff946c1
|
156
|
}
|
segundo |
0:d7810ff946c1
|
157
|
|
segundo |
0:d7810ff946c1
|
158
|
//----------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
159
|
//
|
segundo |
0:d7810ff946c1
|
160
|
// Data transfer functions
|
segundo |
0:d7810ff946c1
|
161
|
//
|
segundo |
0:d7810ff946c1
|
162
|
void write(const T* data, const S cnt);
|
segundo |
0:d7810ff946c1
|
163
|
bool read (T* const data, const S cnt, TTimeout timeout = 0);
|
segundo |
0:d7810ff946c1
|
164
|
|
segundo |
0:d7810ff946c1
|
165
|
void push (const T& item);
|
segundo |
0:d7810ff946c1
|
166
|
void push_front(const T& item);
|
segundo |
0:d7810ff946c1
|
167
|
|
segundo |
0:d7810ff946c1
|
168
|
bool pop (T& item, TTimeout timeout = 0);
|
segundo |
0:d7810ff946c1
|
169
|
bool pop_back(T& item, TTimeout timeout = 0);
|
segundo |
0:d7810ff946c1
|
170
|
|
segundo |
0:d7810ff946c1
|
171
|
|
segundo |
0:d7810ff946c1
|
172
|
//----------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
173
|
//
|
segundo |
0:d7810ff946c1
|
174
|
// Service functions
|
segundo |
0:d7810ff946c1
|
175
|
//
|
segundo |
0:d7810ff946c1
|
176
|
INLINE S get_count() const { TCritSect cs; return pool.get_count(); }
|
segundo |
0:d7810ff946c1
|
177
|
INLINE S get_free_size() const { TCritSect cs; return pool.get_free_size(); }
|
segundo |
0:d7810ff946c1
|
178
|
void flush();
|
segundo |
0:d7810ff946c1
|
179
|
//const T& operator[](const S index) { TCritSect cs; return pool[index]; }
|
segundo |
0:d7810ff946c1
|
180
|
|
segundo |
0:d7810ff946c1
|
181
|
|
segundo |
0:d7810ff946c1
|
182
|
private:
|
segundo |
0:d7810ff946c1
|
183
|
TProcessMap ProducersProcessMap;
|
segundo |
0:d7810ff946c1
|
184
|
TProcessMap ConsumersProcessMap;
|
segundo |
0:d7810ff946c1
|
185
|
usr::ring_buffer<T, Size, S> pool;
|
segundo |
0:d7810ff946c1
|
186
|
|
segundo |
0:d7810ff946c1
|
187
|
private:
|
segundo |
0:d7810ff946c1
|
188
|
void CheckWaiters(TProcessMap& pm);
|
segundo |
0:d7810ff946c1
|
189
|
};
|
segundo |
0:d7810ff946c1
|
190
|
|
segundo |
0:d7810ff946c1
|
191
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
192
|
|
segundo |
0:d7810ff946c1
|
193
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
194
|
//
|
segundo |
0:d7810ff946c1
|
195
|
/// message
|
segundo |
0:d7810ff946c1
|
196
|
///
|
segundo |
0:d7810ff946c1
|
197
|
/// Template for messages
|
segundo |
0:d7810ff946c1
|
198
|
//
|
segundo |
0:d7810ff946c1
|
199
|
// DESCRIPTION:
|
segundo |
0:d7810ff946c1
|
200
|
//
|
segundo |
0:d7810ff946c1
|
201
|
//
|
segundo |
0:d7810ff946c1
|
202
|
class TBaseMessage
|
segundo |
0:d7810ff946c1
|
203
|
{
|
segundo |
0:d7810ff946c1
|
204
|
public:
|
segundo |
0:d7810ff946c1
|
205
|
INLINE TBaseMessage() : ProcessMap(0), NonEmpty(false) { }
|
segundo |
0:d7810ff946c1
|
206
|
|
segundo |
0:d7810ff946c1
|
207
|
bool wait (TTimeout timeout = 0);
|
segundo |
0:d7810ff946c1
|
208
|
void send();
|
segundo |
0:d7810ff946c1
|
209
|
INLINE inline void sendISR();
|
segundo |
0:d7810ff946c1
|
210
|
INLINE bool is_non_empty() const { TCritSect cs; return NonEmpty; }
|
segundo |
0:d7810ff946c1
|
211
|
INLINE void reset () { TCritSect cs; NonEmpty = false; }
|
segundo |
0:d7810ff946c1
|
212
|
|
segundo |
0:d7810ff946c1
|
213
|
private:
|
segundo |
0:d7810ff946c1
|
214
|
TProcessMap ProcessMap;
|
segundo |
0:d7810ff946c1
|
215
|
bool NonEmpty;
|
segundo |
0:d7810ff946c1
|
216
|
};
|
segundo |
0:d7810ff946c1
|
217
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
218
|
template<typename T>
|
segundo |
0:d7810ff946c1
|
219
|
class message : public TBaseMessage
|
segundo |
0:d7810ff946c1
|
220
|
{
|
segundo |
0:d7810ff946c1
|
221
|
public:
|
segundo |
0:d7810ff946c1
|
222
|
INLINE message() : TBaseMessage() { }
|
segundo |
0:d7810ff946c1
|
223
|
INLINE const T& operator=(const T& msg) { TCritSect cs; Msg = msg; return Msg; }
|
segundo |
0:d7810ff946c1
|
224
|
INLINE operator T() const { TCritSect cs; return Msg; }
|
segundo |
0:d7810ff946c1
|
225
|
|
segundo |
0:d7810ff946c1
|
226
|
private:
|
segundo |
0:d7810ff946c1
|
227
|
T Msg;
|
segundo |
0:d7810ff946c1
|
228
|
};
|
segundo |
0:d7810ff946c1
|
229
|
//--------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
230
|
}
|
segundo |
0:d7810ff946c1
|
231
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
232
|
//
|
segundo |
0:d7810ff946c1
|
233
|
// Function-members implementation
|
segundo |
0:d7810ff946c1
|
234
|
//
|
segundo |
0:d7810ff946c1
|
235
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
236
|
void OS::TEventFlag::SignalISR()
|
segundo |
0:d7810ff946c1
|
237
|
{
|
segundo |
0:d7810ff946c1
|
238
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
239
|
if(ProcessMap) // if any process waits for event
|
segundo |
0:d7810ff946c1
|
240
|
{
|
segundo |
0:d7810ff946c1
|
241
|
TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout
|
segundo |
0:d7810ff946c1
|
242
|
// expired, or it was waked up by OS::ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
243
|
if( ProcessMap & ~Timeouted ) // if any process has to be waked up
|
segundo |
0:d7810ff946c1
|
244
|
{
|
segundo |
0:d7810ff946c1
|
245
|
SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
|
segundo |
0:d7810ff946c1
|
246
|
ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
|
segundo |
0:d7810ff946c1
|
247
|
return;
|
segundo |
0:d7810ff946c1
|
248
|
}
|
segundo |
0:d7810ff946c1
|
249
|
}
|
segundo |
0:d7810ff946c1
|
250
|
Value = efOn;
|
segundo |
0:d7810ff946c1
|
251
|
}
|
segundo |
0:d7810ff946c1
|
252
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
253
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
254
|
void OS::channel<T, Size, S>::CheckWaiters(TProcessMap& pm)
|
segundo |
0:d7810ff946c1
|
255
|
{
|
segundo |
0:d7810ff946c1
|
256
|
if(pm)
|
segundo |
0:d7810ff946c1
|
257
|
{
|
segundo |
0:d7810ff946c1
|
258
|
TProcessMap Timeouted = Kernel.ReadyProcessMap;
|
segundo |
0:d7810ff946c1
|
259
|
|
segundo |
0:d7810ff946c1
|
260
|
SetPrioTag(Kernel.ReadyProcessMap, pm); // place all waiting processes to the ready map
|
segundo |
0:d7810ff946c1
|
261
|
ClrPrioTag(pm, ~Timeouted); // remove waiting processes from the wait map
|
segundo |
0:d7810ff946c1
|
262
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
263
|
}
|
segundo |
0:d7810ff946c1
|
264
|
}
|
segundo |
0:d7810ff946c1
|
265
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
266
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
267
|
void OS::channel<T, Size, S>::push(const T& item)
|
segundo |
0:d7810ff946c1
|
268
|
{
|
segundo |
0:d7810ff946c1
|
269
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
270
|
|
segundo |
0:d7810ff946c1
|
271
|
while(!pool.get_free_size())
|
segundo |
0:d7810ff946c1
|
272
|
{
|
segundo |
0:d7810ff946c1
|
273
|
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
|
segundo |
0:d7810ff946c1
|
274
|
SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
|
segundo |
0:d7810ff946c1
|
275
|
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
|
segundo |
0:d7810ff946c1
|
276
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
277
|
}
|
segundo |
0:d7810ff946c1
|
278
|
|
segundo |
0:d7810ff946c1
|
279
|
pool.push_back(item);
|
segundo |
0:d7810ff946c1
|
280
|
CheckWaiters(ConsumersProcessMap);
|
segundo |
0:d7810ff946c1
|
281
|
}
|
segundo |
0:d7810ff946c1
|
282
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
283
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
284
|
void OS::channel<T, Size, S>::push_front(const T& item)
|
segundo |
0:d7810ff946c1
|
285
|
{
|
segundo |
0:d7810ff946c1
|
286
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
287
|
|
segundo |
0:d7810ff946c1
|
288
|
while(!pool.get_free_size())
|
segundo |
0:d7810ff946c1
|
289
|
{
|
segundo |
0:d7810ff946c1
|
290
|
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
|
segundo |
0:d7810ff946c1
|
291
|
SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
|
segundo |
0:d7810ff946c1
|
292
|
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
|
segundo |
0:d7810ff946c1
|
293
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
294
|
}
|
segundo |
0:d7810ff946c1
|
295
|
|
segundo |
0:d7810ff946c1
|
296
|
pool.push_front(item);
|
segundo |
0:d7810ff946c1
|
297
|
CheckWaiters(ConsumersProcessMap);
|
segundo |
0:d7810ff946c1
|
298
|
}
|
segundo |
0:d7810ff946c1
|
299
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
300
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
301
|
bool OS::channel<T, Size, S>::pop(T& item, TTimeout timeout)
|
segundo |
0:d7810ff946c1
|
302
|
{
|
segundo |
0:d7810ff946c1
|
303
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
304
|
|
segundo |
0:d7810ff946c1
|
305
|
if(pool.get_count())
|
segundo |
0:d7810ff946c1
|
306
|
{
|
segundo |
0:d7810ff946c1
|
307
|
item = pool.pop();
|
segundo |
0:d7810ff946c1
|
308
|
CheckWaiters(ProducersProcessMap);
|
segundo |
0:d7810ff946c1
|
309
|
return true;
|
segundo |
0:d7810ff946c1
|
310
|
}
|
segundo |
0:d7810ff946c1
|
311
|
else
|
segundo |
0:d7810ff946c1
|
312
|
{
|
segundo |
0:d7810ff946c1
|
313
|
TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
|
segundo |
0:d7810ff946c1
|
314
|
p->Timeout = timeout;
|
segundo |
0:d7810ff946c1
|
315
|
|
segundo |
0:d7810ff946c1
|
316
|
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
|
segundo |
0:d7810ff946c1
|
317
|
for(;;)
|
segundo |
0:d7810ff946c1
|
318
|
{
|
segundo |
0:d7810ff946c1
|
319
|
SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
|
segundo |
0:d7810ff946c1
|
320
|
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
|
segundo |
0:d7810ff946c1
|
321
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
322
|
|
segundo |
0:d7810ff946c1
|
323
|
if(pool.get_count())
|
segundo |
0:d7810ff946c1
|
324
|
{
|
segundo |
0:d7810ff946c1
|
325
|
p->Timeout = 0;
|
segundo |
0:d7810ff946c1
|
326
|
item = pool.pop();
|
segundo |
0:d7810ff946c1
|
327
|
CheckWaiters(ProducersProcessMap);
|
segundo |
0:d7810ff946c1
|
328
|
return true;
|
segundo |
0:d7810ff946c1
|
329
|
}
|
segundo |
0:d7810ff946c1
|
330
|
|
segundo |
0:d7810ff946c1
|
331
|
if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
|
segundo |
0:d7810ff946c1
|
332
|
{ // or by OS::ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
333
|
|
segundo |
0:d7810ff946c1
|
334
|
p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
335
|
ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
|
segundo |
0:d7810ff946c1
|
336
|
return false;
|
segundo |
0:d7810ff946c1
|
337
|
}
|
segundo |
0:d7810ff946c1
|
338
|
}
|
segundo |
0:d7810ff946c1
|
339
|
}
|
segundo |
0:d7810ff946c1
|
340
|
}
|
segundo |
0:d7810ff946c1
|
341
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
342
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
343
|
bool OS::channel<T, Size, S>::pop_back(T& item, TTimeout timeout)
|
segundo |
0:d7810ff946c1
|
344
|
{
|
segundo |
0:d7810ff946c1
|
345
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
346
|
|
segundo |
0:d7810ff946c1
|
347
|
if(pool.get_count())
|
segundo |
0:d7810ff946c1
|
348
|
{
|
segundo |
0:d7810ff946c1
|
349
|
item = pool.pop_back();
|
segundo |
0:d7810ff946c1
|
350
|
CheckWaiters(ProducersProcessMap);
|
segundo |
0:d7810ff946c1
|
351
|
return true;
|
segundo |
0:d7810ff946c1
|
352
|
}
|
segundo |
0:d7810ff946c1
|
353
|
else
|
segundo |
0:d7810ff946c1
|
354
|
{
|
segundo |
0:d7810ff946c1
|
355
|
TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
|
segundo |
0:d7810ff946c1
|
356
|
p->Timeout = timeout;
|
segundo |
0:d7810ff946c1
|
357
|
|
segundo |
0:d7810ff946c1
|
358
|
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
|
segundo |
0:d7810ff946c1
|
359
|
for(;;)
|
segundo |
0:d7810ff946c1
|
360
|
{
|
segundo |
0:d7810ff946c1
|
361
|
SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
|
segundo |
0:d7810ff946c1
|
362
|
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
|
segundo |
0:d7810ff946c1
|
363
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
364
|
|
segundo |
0:d7810ff946c1
|
365
|
if(pool.get_count())
|
segundo |
0:d7810ff946c1
|
366
|
{
|
segundo |
0:d7810ff946c1
|
367
|
p->Timeout = 0;
|
segundo |
0:d7810ff946c1
|
368
|
item = pool.pop_back();
|
segundo |
0:d7810ff946c1
|
369
|
CheckWaiters(ProducersProcessMap);
|
segundo |
0:d7810ff946c1
|
370
|
return true;
|
segundo |
0:d7810ff946c1
|
371
|
}
|
segundo |
0:d7810ff946c1
|
372
|
|
segundo |
0:d7810ff946c1
|
373
|
if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
|
segundo |
0:d7810ff946c1
|
374
|
{ // or by OS::ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
375
|
|
segundo |
0:d7810ff946c1
|
376
|
p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
377
|
ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
|
segundo |
0:d7810ff946c1
|
378
|
return false;
|
segundo |
0:d7810ff946c1
|
379
|
}
|
segundo |
0:d7810ff946c1
|
380
|
}
|
segundo |
0:d7810ff946c1
|
381
|
}
|
segundo |
0:d7810ff946c1
|
382
|
}
|
segundo |
0:d7810ff946c1
|
383
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
384
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
385
|
void OS::channel<T, Size, S>::flush()
|
segundo |
0:d7810ff946c1
|
386
|
{
|
segundo |
0:d7810ff946c1
|
387
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
388
|
pool.flush();
|
segundo |
0:d7810ff946c1
|
389
|
CheckWaiters(ProducersProcessMap);
|
segundo |
0:d7810ff946c1
|
390
|
}
|
segundo |
0:d7810ff946c1
|
391
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
392
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
393
|
void OS::channel<T, Size, S>::write(const T* data, const S count)
|
segundo |
0:d7810ff946c1
|
394
|
{
|
segundo |
0:d7810ff946c1
|
395
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
396
|
|
segundo |
0:d7810ff946c1
|
397
|
while(pool.get_free_size() < count)
|
segundo |
0:d7810ff946c1
|
398
|
{
|
segundo |
0:d7810ff946c1
|
399
|
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
|
segundo |
0:d7810ff946c1
|
400
|
SetPrioTag(ProducersProcessMap, PrioTag); // channel does not have enough space, put current process to the wait map
|
segundo |
0:d7810ff946c1
|
401
|
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
|
segundo |
0:d7810ff946c1
|
402
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
403
|
}
|
segundo |
0:d7810ff946c1
|
404
|
|
segundo |
0:d7810ff946c1
|
405
|
pool.write(data, count);
|
segundo |
0:d7810ff946c1
|
406
|
CheckWaiters(ConsumersProcessMap);
|
segundo |
0:d7810ff946c1
|
407
|
}
|
segundo |
0:d7810ff946c1
|
408
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
409
|
template<typename T, word Size, typename S>
|
segundo |
0:d7810ff946c1
|
410
|
bool OS::channel<T, Size, S>::read(T* const data, const S count, TTimeout timeout)
|
segundo |
0:d7810ff946c1
|
411
|
{
|
segundo |
0:d7810ff946c1
|
412
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
413
|
|
segundo |
0:d7810ff946c1
|
414
|
TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
|
segundo |
0:d7810ff946c1
|
415
|
p->Timeout = timeout;
|
segundo |
0:d7810ff946c1
|
416
|
|
segundo |
0:d7810ff946c1
|
417
|
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
|
segundo |
0:d7810ff946c1
|
418
|
while(pool.get_count() < count)
|
segundo |
0:d7810ff946c1
|
419
|
{
|
segundo |
0:d7810ff946c1
|
420
|
SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map
|
segundo |
0:d7810ff946c1
|
421
|
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
|
segundo |
0:d7810ff946c1
|
422
|
Kernel.Scheduler();
|
segundo |
0:d7810ff946c1
|
423
|
|
segundo |
0:d7810ff946c1
|
424
|
if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
|
segundo |
0:d7810ff946c1
|
425
|
{ // or by OS::ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
426
|
|
segundo |
0:d7810ff946c1
|
427
|
p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
428
|
ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
|
segundo |
0:d7810ff946c1
|
429
|
return false;
|
segundo |
0:d7810ff946c1
|
430
|
}
|
segundo |
0:d7810ff946c1
|
431
|
}
|
segundo |
0:d7810ff946c1
|
432
|
|
segundo |
0:d7810ff946c1
|
433
|
p->Timeout = 0;
|
segundo |
0:d7810ff946c1
|
434
|
pool.read(data, count);
|
segundo |
0:d7810ff946c1
|
435
|
CheckWaiters(ProducersProcessMap);
|
segundo |
0:d7810ff946c1
|
436
|
|
segundo |
0:d7810ff946c1
|
437
|
return true;
|
segundo |
0:d7810ff946c1
|
438
|
}
|
segundo |
0:d7810ff946c1
|
439
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
440
|
|
segundo |
0:d7810ff946c1
|
441
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
442
|
//
|
segundo |
0:d7810ff946c1
|
443
|
// OS::message template
|
segundo |
0:d7810ff946c1
|
444
|
//
|
segundo |
0:d7810ff946c1
|
445
|
// Function-members implementation
|
segundo |
0:d7810ff946c1
|
446
|
//
|
segundo |
0:d7810ff946c1
|
447
|
//
|
segundo |
0:d7810ff946c1
|
448
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
449
|
void OS::TBaseMessage::sendISR()
|
segundo |
0:d7810ff946c1
|
450
|
{
|
segundo |
0:d7810ff946c1
|
451
|
TCritSect cs;
|
segundo |
0:d7810ff946c1
|
452
|
|
segundo |
0:d7810ff946c1
|
453
|
if(ProcessMap)
|
segundo |
0:d7810ff946c1
|
454
|
{
|
segundo |
0:d7810ff946c1
|
455
|
TProcessMap Timeouted = OS::Kernel.ReadyProcessMap; // Process has it's tag set in ReadyProcessMap if timeout
|
segundo |
0:d7810ff946c1
|
456
|
// expired, or it was waked up by OS::ForceWakeUpProcess()
|
segundo |
0:d7810ff946c1
|
457
|
if( ProcessMap & ~Timeouted ) // if any process has to be waked up
|
segundo |
0:d7810ff946c1
|
458
|
{
|
segundo |
0:d7810ff946c1
|
459
|
SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
|
segundo |
0:d7810ff946c1
|
460
|
ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
|
segundo |
0:d7810ff946c1
|
461
|
return;
|
segundo |
0:d7810ff946c1
|
462
|
}
|
segundo |
0:d7810ff946c1
|
463
|
}
|
segundo |
0:d7810ff946c1
|
464
|
NonEmpty = true;
|
segundo |
0:d7810ff946c1
|
465
|
}
|
segundo |
0:d7810ff946c1
|
466
|
//------------------------------------------------------------------------------
|
segundo |
0:d7810ff946c1
|
467
|
#endif // OS_SERVICES_H
|