Committer:
segundo
Date:
Thu Nov 11 10:30:39 2010 +0000
Revision:
7:6fab7e5aa489
Parent:
0:d7810ff946c1

        

Who changed what in which revision?

UserRevisionLine numberNew 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