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

uStaticPriorityQ.h

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Ashif S. Harji 2000
// 
// uStaticPriorityQ.h -- 
// 
// Author           : Ashif S. Harji
// Created On       : Fri Jan 14 17:59:34 2000
// Last Modified By : Peter A. Buhr
// Last Modified On : Sun Aug  8 09:04:28 2004
// Update Count     : 62
//
// 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_STATICPRIORITYQ_H__
#define __U_STATICPRIORITYQ_H__

#pragma __U_NOT_USER_CODE__


//#include <uDebug.h>

#include <uC++.h>
#include <uStaticPIQ.h>

#include <cstring>                              // access: ffs


#define __U_MAX_NUMBER_PRIORITIES__ 32


class uStaticPriorityQ : public uBasePrioritySeq {
  protected:
    uBaseTaskSeq uObjects[__U_MAX_NUMBER_PRIORITIES__];
    unsigned int uMask;                         // allow access to all queue flags

    int uCurrPriority;
  public:
    uStaticPriorityQ();
    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 );

    int uAfterEntry( uBaseTask *uOwner );
}; // StaticPriorityQ


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

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

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

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

    virtual void uAdd( Node *node ) {
      int priority = uGetActivePriorityValue( 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( "(uStaticPriorityScheduleQ &)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__
    } // uStaticPriorityScheduleQ::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( "(uStaticPriorityScheduleQ &)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
    } // uStaticPriorityScheduleQ::uDrop

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

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

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

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

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


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

    virtual void uResetPriority( Node &owner, Node &calling ) {
      int priority;
      uBaseTask &uOwner = owner.uGet();
      uBaseTask &uCalling = calling.uGet();
      // if same, update owner based on uPIQ
      if ( &uOwner == &uCalling ) {
          priority = (static_cast<uStaticPIQ *>(uOwner.uPIQ))->uGetHighestPriority(); // TODO: dynamic needed???
          // if no inheritance priority use base priority
          if ( priority == -1 ) {
            priority = uOwner.uGetBasePriority();
          } // if
      } else {  // otherwise, update to atmost calling task's priority
          if ( uCalling.uGetActivePriorityValue() > uOwner.uGetActivePriorityValue() ) return;
          priority = uCalling.uGetActivePriorityValue();
      } // if
            
      if ( owner.uListed() ) {
          uRemove( &owner );
          uSetActivePriority( uOwner, priority );
          uAdd( &owner );
      } else {
          uSetActivePriority( uOwner, priority );
      } // if
    } // uPriorityScheduleSeq::uResetPriority

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


#endif //  __U_STATICPRIORITYQ_H__


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

Generated by  Doxygen 1.6.0   Back to index