Dependencies:   mbed

Committer:
mbed714
Date:
Tue Sep 21 19:48:05 2010 +0000
Revision:
0:331db0b44b67

        

Who changed what in which revision?

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