Logo Search packages:      
Sourcecode: u++ version File versions

uRealTime.cc

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Peter A. Buhr 1999
// 
// uRealTime.cc -- 
// 
// Author           : Peter A. Buhr
// Created On       : Mon Feb  1 15:06:12 1999
// Last Modified By : Peter A. Buhr
// Last Modified On : Mon Jun 28 09:58:33 2004
// Update Count     : 25
//
// This  library is free  software; you  can redistribute  it and/or  modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
// option) any later version.
// 
// This library is distributed in the  hope that it will be useful, but WITHOUT
// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
// for more details.
// 
// You should  have received a  copy of the  GNU Lesser General  Public License
// along  with this library.
// 

#define __U_KERNEL__
#include <uC++.h>
#include <uRealTime.h>
//#include <uDebug.h>


//######################### uPrioritySeq #########################


uPrioritySeq::uPrioritySeq() {                        
    uMask = 0;
    uExecuteHooks = true;
} // uPrioritySeq::uPriorityScheduleQueue

bool uPrioritySeq::uEmpty() const {             
    return uMask == 0;
} // uPrioritySeq::uEmpty

uBaseTaskDL *uPrioritySeq::uHead() const {                  
    int highestPriority = ffs( uMask ) - 1;

    if ( highestPriority >= 0 ) {
      uBaseTaskDL *node = uObjects[highestPriority].uHead();
      return node;
    } else {
      return NULL;
    } // if
} // uPrioritySeq::uHead

int uPrioritySeq::uAdd( uBaseTaskDL *node, uBaseTask *uOwner ) {
    int priority = uGetActivePriority( node->uGet() );
    uAssert( 0 <= priority && priority <= __U_MAX_NUMBER_PRIORITIES__ - 1 );
    uObjects[priority].uAdd( node );
    uMask |= 1ul << priority;
#ifdef __U_DEBUG_H__
    uDebugPrt( "(uPriorityScheduleQueue &)0x%p.uAdd( 0x%p ) task %.256s (0x%p) adding task %.256s (0x%p) with priority %d on cluster 0x%p\n",
             this, node, uThisTask().uGetName(), &uThisTask(), node->uGet().uGetName(), &node->uGet(), priority, &uThisCluster() );
#endif // __U_DEBUG_H__
    // only perform inheritance for entry list
    if ( uIsEntryBlocked( node->uGet() ) && uCheckHookConditions( *uOwner, node->uGet() ) ) {   // TEMP: entry queue??
      return( uAfterEntry( uOwner ) );          // perform any priority inheritance
    } else {
      return 0;
    } // if
} // uPriorityScheduleQueue::uAdd

uBaseTaskDL *uPrioritySeq::uDrop() {                        
    int highestPriority = ffs( uMask ) - 1;

    if ( highestPriority >= 0 ) {
      uBaseTaskDL *node = uObjects[highestPriority].uDrop();
      if ( uObjects[highestPriority].uEmpty() ) {
          uMask &= ~ ( 1ul << highestPriority );
      } // if
#ifdef __U_DEBUG_H__
      uDebugPrt( "(uPriorityScheduleQueue &)0x%p.uDrop( 0x%p ) task %.256s (0x%p) removing task %.256s (0x%p) with priority %d on cluster 0x%p\n",
               this, node, uThisTask().uGetName(), &uThisTask(), node->uGet().uGetName(), &node->uGet(), highestPriority, &uThisCluster() );
#endif // __U_DEBUG_H__
      return node;
    } else {
      return NULL;
    } // if
} // uPrioritySeq::uDrop

void uPrioritySeq::uRemove( uBaseTaskDL *node ) {           
      int priority = uGetActivePriority( node->uGet() );
      uObjects[priority].uRemove( node );
      if ( uObjects[priority].uEmpty() ) {
          uMask &= ~ ( 1ul << priority );
      } // if
} // uPrioritySeq::uRemove

int uPrioritySeq::uAfterEntry( uBaseTask *uOwner ) {
    if ( ! uEmpty() ) {
      uThisCluster().uTaskResetPriority( *uOwner, uHead()->uGet() );
    } // if
    return 0;
} // uPrioritySeq::uAfterEntry

void uPrioritySeq::uOnAcquire(uBaseTask &uOwner ) {
    uOldInheritTask = &uGetInheritTask( uOwner );
    uAfterEntry( &uOwner );
} // uPrioritySeq::uOnAcquire

void uPrioritySeq::uOnRelease(uBaseTask &uOwner ) {
    // no queue adjustment as task is running
    uSetActivePriority( uOwner, *uOldInheritTask );
} // uPrioritySeq::uOnRelease


//######################### uRealTimeBaseTask #########################


uRealTimeBaseTask::uRealTimeBaseTask( uCluster &cluster ) : uBaseTask( cluster ) {};

uRealTimeBaseTask::uRealTimeBaseTask( uTime FirstActivateT, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uBaseTask( cluster ) {
    if ( Deadline < 0 ) {
      uAbort( ": attempt to create real time task with deadline less than 0." );
    } // if
    uFirstActivateTime = FirstActivateT;
    uEndTime = EndTime;
    uDeadline = Deadline;
} // uRealTimeBaseTask::uRealTimeBaseTask

uRealTimeBaseTask::uRealTimeBaseTask( uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uBaseTask( cluster ) {
    if ( Deadline < 0 ) {
      uAbort( ": attempt to create real time task with deadline less than 0." );
    } // if
    uFirstActivateEvent = FirstActivateE;
    uFirstActivateTime = 0;
    uEndTime = EndTime;
    uDeadline = Deadline;
} // uRealTimeBaseTask::uRealTimeBaseTask

uRealTimeBaseTask::uRealTimeBaseTask( uTime FirstActivateT, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uBaseTask( cluster ) {
    if ( Deadline < 0 ) {
      uAbort( ": attempt to create real time task with deadline less than 0." );
    } // if
    uFirstActivateTime = FirstActivateT;
    uFirstActivateEvent = FirstActivateE;
    uEndTime = EndTime;
    uDeadline = Deadline;
} // uRealTimeBaseTask::uRealTimeBaseTask

uRealTimeBaseTask::~uRealTimeBaseTask() {
    while( ! uVerCountSeq.uEmpty() ) {                // remove list of version counts
      delete uVerCountSeq.uDropHead();
    } // while
} // uRealTimeBaseTask::uRealTimeBaseTask

uDuration uRealTimeBaseTask::uGetDeadline() const {
    return uDeadline;
} // uRealTimeBaseTask::uGetDeadline

uDuration uRealTimeBaseTask::uSetDeadline( uDuration Deadline ) {
#ifdef __U_DEBUG__
    if ( this != &uThisTask() ) {
      uAbort( ": attempt to change the deadline of task %.256s (0x%p).\n"
            "A task can only change its own deadline.\n",
            uGetName(), this );
    } // if
#endif // __U_DEBUG__

    // A simple optimization: changing the deadline of a task to its existing
    // value does not require a recalculation of priorities.
      
  if ( Deadline == uDeadline ) return uDeadline;

    uDuration temp = uDeadline;
    uDeadline = Deadline;
    uThisCluster().uTaskReschedule( *this );
    uYield();
    return temp;
} // uRealTimeBaseTask::uSetDeadline

int uRealTimeBaseTask::uGetVersion( uCluster &cluster ) {
    uSeqGen<uVerCount> i;
    uVerCount *node = NULL;

    for ( i.uOver( uVerCountSeq ); i >> node; ) { 
      if ( node->cluster == &cluster ) {
          return node->version;
      } // if
    } // for

    return -1;
} // uRealTimeBaseTask::uGetVersion
    
int uRealTimeBaseTask::uSetVersion( uCluster &cluster, int version ) {
    uSeqGen<uVerCount> i;
    uVerCount *ref = NULL, *node = NULL, *prev = NULL;
    int temp;

    for ( i.uOver(uVerCountSeq), prev = NULL; i >> node ; prev = node ) { // find place in the list to insert
      if ( &cluster < node->cluster ) break;
    } // for

    if ( prev != NULL && prev->cluster == &cluster ) {
      temp = prev->version; 
      prev->version = version;
    } else {
      temp = -1;
      ref = new uVerCount;
      ref->cluster = &cluster;
      ref->version = version;
      uVerCountSeq.uInsertBef( ref, node );
    } // if

    return temp;
} // uRealTimeBaseTask::uSetVersion


//######################### uPeriodicBaseTask #########################


uPeriodicBaseTask::uPeriodicBaseTask( uDuration Period, uCluster &cluster ) : uRealTimeBaseTask( uTime(0), uTime(0), uDuration(0), cluster ) {
    uPeriod = Period;
} // uPeriodicBaseTask::uPeriodicBaseTask

uPeriodicBaseTask::uPeriodicBaseTask( uDuration Period, uTime FirstActivateT, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uRealTimeBaseTask( FirstActivateT, EndTime, Deadline, cluster ) {
    uPeriod = Period;
} // uPeriodicBaseTask::uPeriodicBaseTask

uPeriodicBaseTask::uPeriodicBaseTask( uDuration Period, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uRealTimeBaseTask( FirstActivateE, EndTime, Deadline, cluster ) {
    uPeriod = Period;
} // uPeriodicBaseTask::uPeriodicBaseTask

uPeriodicBaseTask::uPeriodicBaseTask( uDuration Period, uTime FirstActivateT, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uRealTimeBaseTask( FirstActivateT, FirstActivateE, EndTime, Deadline, cluster ) {
    uPeriod = Period;
} // uPeriodicBaseTask::uPeriodicBaseTask

uDuration uPeriodicBaseTask::uGetPeriod() const {
    return uPeriod;
} // uPeriodicBaseTask::uGetPeriod

uDuration uPeriodicBaseTask::uSetPeriod( uDuration period ) {
#ifdef __U_DEBUG__
    if ( this != &uThisTask() ) {
      uAbort( ": attempt to change the period of task %.256s (0x%p).\n"
            "A task can only change its own period.\n",
            uGetName(), this );
    } // if
#endif // __U_DEBUG__

    // A simple optimization: changing the period of a task to its existing
    // value does not require a recalculation of priorities.
      
  if ( period == uPeriod ) return uPeriod;

    uDuration temp = uPeriod;
    uPeriod = period;
    uThisCluster().uTaskReschedule( *this );
    uYield();
    return temp;
} // uPeriodicBaseTask::uSetPeriod


//######################### uSporadicBaseTask #########################


uSporadicBaseTask::uSporadicBaseTask( uDuration Frame, uCluster &cluster ) : uRealTimeBaseTask( uTime(0), uTime(0), uDuration(0), cluster ) {
    uFrame = Frame;
} // uSporadicBaseTask::uSporadicBaseTask

uSporadicBaseTask::uSporadicBaseTask( uDuration Frame, uTime FirstActivateT, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uRealTimeBaseTask( FirstActivateT, EndTime, Deadline, cluster ) {
    uFrame = Frame;
} // uSporadicBaseTask::uSporadicBaseTask

uSporadicBaseTask::uSporadicBaseTask( uDuration Frame, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uRealTimeBaseTask( FirstActivateE, EndTime, Deadline, cluster ) {
    uFrame = Frame;
} // uSporadicBaseTask::uSporadicBaseTask

uSporadicBaseTask::uSporadicBaseTask( uDuration Frame, uTime FirstActivateT, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster ) : uRealTimeBaseTask( FirstActivateT, FirstActivateE, EndTime, Deadline, cluster ) {
    uFrame = Frame;
} // uSporadicBaseTask::uSporadicBaseTask

uDuration uSporadicBaseTask::uGetFrame() const {
    return uFrame;
} // uSporadicBaseTask::uGetFrame

uDuration uSporadicBaseTask::uSetFrame( uDuration frame ) {
#ifdef __U_DEBUG__
    if ( this != &uThisTask() ) {
      uAbort( ": attempt to change the frame of task %.256s (0x%p).\n"
            "A task can only change its own frame.\n",
            uGetName(), this );
    } // if
#endif // __U_DEBUG__

    // A simple optimization: changing the frame of a task to its existing
    // value does not require a recalculation of priorities.
      
  if ( frame == uFrame ) return uFrame;

    uDuration temp = uFrame;
    uFrame = frame;
    uThisCluster().uTaskReschedule( *this );
    uYield();
    return temp;
} // uSporadicBaseTask::uSetFrame


//######################### uRealTimeCluster #########################


uRealTimeCluster::uRealTimeCluster( uBaseSchedule<uBaseTaskDL> &rq, int size, const char *name ) : uCluster( rq, size, name ) {};
uRealTimeCluster::uRealTimeCluster( uBaseSchedule<uBaseTaskDL> &rq, const char *name ) : uCluster( rq, name ) {};
uRealTimeCluster::~uRealTimeCluster() {};


// Local Variables: //
// compile-command: "gmake install" //
// End: //

Generated by  Doxygen 1.6.0   Back to index