chokchai Hantanong
/
RtosTest
LED Fork
Fork of RtosTest by
Diff: scmRTOS/Common/OS_Services.cpp
- Revision:
- 1:a33478a10fd0
- Parent:
- 0:331db0b44b67
diff -r 331db0b44b67 -r a33478a10fd0 scmRTOS/Common/OS_Services.cpp --- a/scmRTOS/Common/OS_Services.cpp Tue Sep 21 19:48:05 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,298 +0,0 @@ -//****************************************************************************** -//* -//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System -//* -//* NICKNAME: scmRTOS -//* -//* PURPOSE: OS Services Source -//* -//* Version: 3.10 -//* -//* $Revision: 256 $ -//* $Date:: 2010-01-22 #$ -//* -//* Copyright (c) 2003-2010, Harry E. Zhurov -//* -//* Permission is hereby granted, free of charge, to any person -//* obtaining a copy of this software and associated documentation -//* files (the "Software"), to deal in the Software without restriction, -//* including without limitation the rights to use, copy, modify, merge, -//* publish, distribute, sublicense, and/or sell copies of the Software, -//* and to permit persons to whom the Software is furnished to do so, -//* subject to the following conditions: -//* -//* The above copyright notice and this permission notice shall be included -//* in all copies or substantial portions of the Software. -//* -//* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -//* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -//* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -//* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -//* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH -//* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -//* -//* ================================================================= -//* See http://scmrtos.sourceforge.net for documentation, latest -//* information, license and contact details. -//* ================================================================= -//* -//****************************************************************************** - -#include "scmRTOS.h" - -using namespace OS; - -//------------------------------------------------------------------------------ -// -// -// TEventFlag -// -// -bool OS::TEventFlag::Wait(TTimeout timeout) -{ - TCritSect cs; - - if(Value) // if flag already signaled - { - Value = efOff; // clear flag - return true; - } - else - { - TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; - p->Timeout = timeout; - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - - SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - - Kernel.Scheduler(); - - p->Timeout = 0; - - if( !(ProcessMap & PrioTag) ) // if waked up by signal() or signal_ISR() - return true; - - ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by - return false; // OS::ForceWakeUpProcess(), remove process from the wait map - } -} -//------------------------------------------------------------------------------ -void OS::TEventFlag::Signal() -{ - TCritSect cs; - if(ProcessMap) // if any process waits for event - { - TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout expired - // or it was waked up by OS::ForceWakeUpProcess() - - if( ProcessMap & ~Timeouted ) // if any process has to be waked up - { - SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map - ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map. - // Used to check that process waked up by signal() or signalISR() - // and not by timeout or OS::ForceWakeUpProcess() - Kernel.Scheduler(); - return; - } - } - Value = efOn; -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// -// -// TMutex -// -// -void OS::TMutex::Lock() -{ - TCritSect cs; - - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - while(ValueTag) - { - SetPrioTag(ProcessMap, PrioTag); // mutex already locked by another process, put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - - Kernel.Scheduler(); - } - ValueTag = PrioTag; // mutex has been successfully locked -} -//------------------------------------------------------------------------------ -void OS::TMutex::Unlock() -{ - TCritSect cs; - - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - if(ValueTag != PrioTag) return; // the only process that had locked mutex can unlock the mutex - ValueTag = 0; - if(ProcessMap) - { - byte pr = GetHighPriority(ProcessMap); - PrioTag = GetPrioTag(pr); - ClrPrioTag(ProcessMap, PrioTag); // remove next ready process from the wait map - SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map - Kernel.Scheduler(); - } -} -//------------------------------------------------------------------------------ -void OS::TMutex::UnlockISR() -{ - TCritSect cs; - - ValueTag = 0; - if(ProcessMap) - { - byte pr = GetHighPriority(ProcessMap); - TProcessMap PrioTag = GetPrioTag(pr); - ClrPrioTag(ProcessMap, PrioTag); // remove next ready process from the wait map - SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map - } -} -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// -// -// TChannel -// -// -void OS::TChannel::CheckWaiters(TProcessMap& pm) -{ - if(pm) - { - byte pr = GetHighPriority(pm); - TProcessMap PrioTag = GetPrioTag(pr); - ClrPrioTag(pm, PrioTag); // remove next ready process from the wait map - SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map - Kernel.Scheduler(); - } -} -//------------------------------------------------------------------------------ -void OS::TChannel::Push(byte x) -{ - TCritSect cs; - - while (!Cbuf.get_free_size()) - { - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - SetPrioTag (ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - Kernel.Scheduler(); // wait until waked-up by Pop() or Read() - } - - Cbuf.put(x); - CheckWaiters(ConsumersProcessMap); -} -//------------------------------------------------------------------------------ -byte OS::TChannel::Pop() -{ - TCritSect cs; - byte x; - - while(!Cbuf.get_count()) - { - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - Kernel.Scheduler(); // wait until waked up by Push() or Write() - } - x = Cbuf.get(); - CheckWaiters(ProducersProcessMap); - return x; -} -//------------------------------------------------------------------------------ -void OS::TChannel::Write(const byte* data, const byte count) -{ - TCritSect cs; - - while(Cbuf.get_free_size() < count) - { - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - SetPrioTag(ProducersProcessMap, PrioTag); // channel has not enough space, put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - Kernel.Scheduler(); // wait until waked up by Read() or Pop() - } - - Cbuf.write(data, count); - CheckWaiters(ConsumersProcessMap); -} -//------------------------------------------------------------------------------ -void OS::TChannel::Read(byte* const data, const byte count) -{ - TCritSect cs; - - while(Cbuf.get_count() < count) - { - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - Kernel.Scheduler(); // wait until waked up by Write() or Push() - } - - Cbuf.read(data, count); - CheckWaiters(ProducersProcessMap); -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// -// OS::message template -// -// Function-members implementation -// -// -//------------------------------------------------------------------------------ -bool OS::TBaseMessage::wait(TTimeout timeout) -{ - TCritSect cs; - - if(NonEmpty) // message alredy send - { - NonEmpty = false; - return true; - } - else - { - TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; - p->Timeout = timeout; - TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); - - SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map - ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map - Kernel.Scheduler(); // wait until wake up - - p->Timeout = 0; - if( !(ProcessMap & PrioTag) ) // if waked up by send() or sendISR() - return true; - - ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by - return false; // OS::ForceWakeUpProcess(), remove process from wait map - } -} -//------------------------------------------------------------------------------ -void OS::TBaseMessage::send() -{ - TCritSect cs; - - if(ProcessMap) - { - TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout expired, - // or it was waked up by OS::ForceWakeUpProcess() - if( ProcessMap & ~Timeouted ) // if any process has to be waked up - { - SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map - ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map. - Kernel.Scheduler(); - return; - } - } - - NonEmpty = true; -} -//------------------------------------------------------------------------------ -