Quick and dirty port of scmRTOS demo to mbed 1768. scmRTOS is a small RTOS written using C++. Offers (static) processes, critical sections, mutexes, messages, channels.

Dependencies:   mbed

Committer:
igorsk
Date:
Thu Sep 09 21:19:01 2010 +0000
Revision:
0:a405220cf420

        

Who changed what in which revision?

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