Dependencies:   PinDetect TextLCD mbed mRotaryEncoder

Committer:
cicklaus
Date:
Mon Feb 13 02:11:20 2012 +0000
Revision:
0:afb2650fb49a

        

Who changed what in which revision?

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