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

uRealTime.h

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Philipp E. Lim 1996
// 
// uRealTime.h -- 
// 
// Author           : Philipp E. Lim
// Created On       : Fri Jul 19 16:34:59 1996
// Last Modified By : Peter A. Buhr
// Last Modified On : Sun Aug  8 09:04:56 2004
// Update Count     : 73
//
// 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.
// 


#ifndef __U_REALTIME_H__
#define __U_REALTIME_H__

#pragma __U_NOT_USER_CODE__


//#include <uDebug.h>
#include <cstring>                              // access: ffs


// provide default definition for real-time monitor
#define uRealTimeMonitor uMutex<uPrioritySeq,uPrioritySeq> class

// Faked for now, since Events aren't implemented yet.
class uEvent {
  public:
    uEvent() {};
    //     uEvent(int x) {};
};


//######################### Priority Scheduling #########################


#define __U_MAX_NUMBER_PRIORITIES__ 32


template<class List, class Node> class uPriorityScheduleQueue : public uBaseSchedule<Node> {
  protected:
    List uObjects[__U_MAX_NUMBER_PRIORITIES__];
    unsigned int uMask;                         // allow access to all queue flags
    unsigned int verCount;
  public:
    uPriorityScheduleQueue() {
      verCount = uMask = 0;
    } // uPriorityScheduleQueue::uPriorityScheduleQueue

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

    virtual Node *uHead() const {
      int highestPriority = ffs( uMask ) - 1;

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

    virtual void uAdd( Node *node ) {
      int priority = uGetActivePriority( node->uGet() );
#ifdef __U_DEBUG__
      uAssert( 0 <= priority && priority <= __U_MAX_NUMBER_PRIORITIES__ - 1 );
#endif // __U_DEBUG__
      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__
    } // uPriorityScheduleQueue::uAdd

    virtual Node *uDrop() {
      int highestPriority = ffs( uMask ) - 1;

      if ( highestPriority >= 0 ) {
          Node *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
    } // uPriorityScheduleQueue::uDrop

    virtual bool uCheckPriority( Node &, Node & ) {
      return false;
    } // uPriorityScheduleQueue::uCheckPriority

    virtual void uResetPriority( Node &, Node & ) {
    } // uPriorityScheduleQueue::uResetPriority

    virtual void uAddInitialize( uBaseTaskSeq & ) {
    } // uPriorityScheduleQueue::uAddInitialize

    virtual void uRemoveInitialize( uBaseTaskSeq & ) {
    } // uPriorityScheduleQueue::uRemoveInitialize

    virtual void uRescheduleTask( uBaseTaskDL *, uBaseTaskSeq & ) {
    } // uPriorityScheduleQueue::uRescheduleTask
}; // uPriorityScheduleQueue


class uPrioritySeq : public uBasePrioritySeq {
  protected:
    uBaseTaskSeq uObjects[__U_MAX_NUMBER_PRIORITIES__];
    unsigned int uMask;                         // allow access to all queue flags
    uBaseTask *uOldInheritTask;
    int uAfterEntry( uBaseTask *uOwner );
  public:
    uPrioritySeq();
    virtual bool uEmpty() const;
    virtual uBaseTaskDL *uHead() const;
    virtual int uAdd( uBaseTaskDL *node, uBaseTask *uOwner );
    virtual uBaseTaskDL *uDrop();
    virtual void uRemove( uBaseTaskDL *node );
    virtual void uOnAcquire(uBaseTask &uOldOwner );
    virtual void uOnRelease( uBaseTask &uOwner );
}; // uPrioritySeq


template<class List, class Node> class uPriorityScheduleSeq : public uPriorityScheduleQueue<List, Node> {
    using uPriorityScheduleQueue<List, Node>::uObjects;
    using uPriorityScheduleQueue<List, Node>::uMask;
  public:
    virtual bool uCheckPriority( Node &owner, Node &calling ) {
      return uGetActivePriority( owner.uGet() ) > uGetActivePriority( calling.uGet() );
    } // uPriorityScheduleSeq::uCheckPriority

    virtual void uResetPriority( Node &owner, Node &calling ) {
      if ( owner.uListed() ) {
          uRemove( &owner );
          uSetActivePriority( owner.uGet(), calling.uGet() );
          uAdd( &owner );
      } else {
          uSetActivePriority( owner.uGet(), calling.uGet() );
      } // if
    } // uPriorityScheduleSeq::uResetPriority

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


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


class uRealTimeBaseTask : public uBaseTask {
    class uVerCount : public uSeqable {
      public:
      int version;
      uCluster *cluster;
    }; // uVerCount

    uDuration uDeadline;
    uSequence<uVerCount> uVerCountSeq;                  // list of scheduler version counts with associated cluster 
  protected: 
    uTime uFirstActivateTime;
    uEvent uFirstActivateEvent;
    uTime uEndTime;
  public:
    uRealTimeBaseTask( uCluster &cluster = uThisCluster() );
    uRealTimeBaseTask( uTime FirstActivateT, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uRealTimeBaseTask( uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uRealTimeBaseTask( uTime FirstActivateT, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    ~uRealTimeBaseTask();
    virtual uDuration uGetDeadline() const;
    virtual uDuration uSetDeadline( uDuration Deadline );

    // These members should be private but cannot be because they are
    // referenced from user code.

    virtual int uGetVersion( uCluster &cluster );
    virtual int uSetVersion( uCluster &cluster, int version );
}; // uRealTimeBaseTask


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


class uPeriodicBaseTask : public uRealTimeBaseTask {
  protected:
    uDuration uPeriod;
  public:
    uPeriodicBaseTask( uDuration Period, uCluster &cluster = uThisCluster() );
    uPeriodicBaseTask( uDuration Period, uTime FirstActivateT, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uPeriodicBaseTask( uDuration Period, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uPeriodicBaseTask( uDuration Period, uTime FirstActivateT, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uDuration uGetPeriod() const;
    uDuration uSetPeriod( uDuration period );
}; // uPeriodicBaseTask


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


class uSporadicBaseTask : public uRealTimeBaseTask {
  protected:
    uDuration uFrame;
  public:
    uSporadicBaseTask( uDuration Frame, uCluster &cluster = uThisCluster() );
    uSporadicBaseTask( uDuration Frame, uTime FirstActivateT, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uSporadicBaseTask( uDuration Frame, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uSporadicBaseTask( uDuration Frame, uTime FirstActivateT, uEvent FirstActivateE, uTime EndTime, uDuration Deadline, uCluster &cluster = uThisCluster() );
    uDuration uGetFrame() const;
    uDuration uSetFrame( uDuration frame );
}; // uSporadicBaseTask


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


class uRealTimeCluster : public uCluster {
  public:
    uRealTimeCluster( uBaseSchedule<uBaseTaskDL> &rq, int size = uDefaultStackSize(), const char *name = "uRealTimeCluster" );
    uRealTimeCluster( uBaseSchedule<uBaseTaskDL> &rq, const char *name );
    ~uRealTimeCluster();
}; // uRealTimeCluster


#pragma __U_USER_CODE__

#endif // __U_REALTIME_H__


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

Generated by  Doxygen 1.6.0   Back to index