URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [include/] [mlqueue.hxx] - Rev 811
Go to most recent revision | Compare with Previous | Blame | View Log
#ifndef CYGONCE_KERNEL_MLQUEUE_HXX
#define CYGONCE_KERNEL_MLQUEUE_HXX
//==========================================================================
//
// mlqueue.hxx
//
// Multi-Level Queue scheduler class declarations
//
//==========================================================================
// ####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later
// version.
//
// eCos 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with eCos; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// As a special exception, if other files instantiate templates or use
// macros or inline functions from this file, or you compile this file
// and link it with other works to produce a work based on this file,
// this file does not by itself cause the resulting work to be covered by
// the GNU General Public License. However the source code for this file
// must still be made available in accordance with section (3) of the GNU
// General Public License v2.
//
// This exception does not invalidate any other reasons why a work based
// on this file might be covered by the GNU General Public License.
// -------------------------------------------
// ####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: jlarmour
// Date: 1997-09-10
// Purpose: Define multilevel queue scheduler implementation
// Description: The classes defined here are used as base classes
// by the common classes that define schedulers and thread
// things. The MLQ scheduler in various configurations
// provides standard FIFO, round-robin and single priority
// schedulers.
// Usage: Included according to configuration by
// <cyg/kernel/sched.hxx>
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <cyg/kernel/ktypes.h>
#include <cyg/infra/clist.hxx> // List implementation
// -------------------------------------------------------------------------
// The macro CYGNUM_KERNEL_SCHED_PRIORITIES contains the number of priorities
// supported by the scheduler.
#ifndef CYGNUM_KERNEL_SCHED_PRIORITIES
#define CYGNUM_KERNEL_SCHED_PRIORITIES 32 // define a default
#endif
// set bitmap size
#define CYGNUM_KERNEL_SCHED_BITMAP_SIZE CYGNUM_KERNEL_SCHED_PRIORITIES
// -------------------------------------------------------------------------
// The macro CYGNUM_KERNEL_SCHED_BITMAP_SIZE contains the number of bits that the
// scheduler bitmap should contain. It is derived from the number of prioirity
// levels defined by the configuration.
#if CYGNUM_KERNEL_SCHED_BITMAP_SIZE <= 8
typedef cyg_ucount8 cyg_sched_bitmap;
#elif CYGNUM_KERNEL_SCHED_BITMAP_SIZE <= 16
typedef cyg_ucount16 cyg_sched_bitmap;
#elif CYGNUM_KERNEL_SCHED_BITMAP_SIZE <= 32
typedef cyg_ucount32 cyg_sched_bitmap;
#else
#error Bitmaps greater than 32 bits not currently allowed
#endif
// -------------------------------------------------------------------------
// Customize the scheduler
#define CYGIMP_THREAD_PRIORITY 1 // Threads have changable priorities
#define CYG_THREAD_MIN_PRIORITY (CYGNUM_KERNEL_SCHED_PRIORITIES-1)
#define CYG_THREAD_MAX_PRIORITY 0
// set default scheduling info value for thread constructors.
#define CYG_SCHED_DEFAULT_INFO CYG_THREAD_MAX_PRIORITY
// -------------------------------------------------------------------------
// scheduler Run queue object
typedef Cyg_CList_T<Cyg_Thread> Cyg_RunQueue;
// -------------------------------------------------------------------------
// Thread queue implementation.
// This class provides the (scheduler specific) implementation of the
// thread queue class.
class Cyg_ThreadQueue_Implementation
: public Cyg_CList_T<Cyg_Thread>
{
friend class Cyg_Scheduler_Implementation;
friend class Cyg_SchedThread_Implementation;
void set_thread_queue(Cyg_Thread *thread,
Cyg_ThreadQueue *tq );
protected:
// API used by Cyg_ThreadQueue
Cyg_ThreadQueue_Implementation() {}; // Constructor
// Add thread to queue
void enqueue(Cyg_Thread *thread);
// return first thread on queue
Cyg_Thread *highpri();
// remove first thread on queue
Cyg_Thread *dequeue();
// Remove thread from queue
void remove(Cyg_Thread *thread);
};
// -------------------------------------------------------------------------
// This class contains the implementation details of the scheduler, and
// provides a standard API for accessing it.
class Cyg_Scheduler_Implementation
: public Cyg_Scheduler_Base
{
friend class Cyg_ThreadQueue_Implementation;
friend class Cyg_SchedThread_Implementation;
friend class Cyg_HardwareThread;
friend void cyg_scheduler_set_need_reschedule();
// Mask of which run queues have ready threads
cyg_sched_bitmap queue_map;
// Each run queue is a double linked circular list of threads.
// These pointers point to the head element of each list.
Cyg_RunQueue run_queue[CYGNUM_KERNEL_SCHED_PRIORITIES];
#ifdef CYGPKG_KERNEL_SMP_SUPPORT
// In SMP systems we additionally keep a counter for each priority
// of the number of pending but not running threads in each queue.
cyg_uint32 pending[CYGNUM_KERNEL_SCHED_PRIORITIES];
cyg_sched_bitmap pending_map;
#endif
protected:
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
// Timeslice counter. This is decremented on each
// clock tick, and a timeslice is performed each
// time it zeroes.
static cyg_ucount32 timeslice_count[CYGNUM_KERNEL_CPU_MAX]
CYGBLD_ANNOTATE_VARIABLE_SCHED;
#endif
Cyg_Scheduler_Implementation(); // Constructor
// The following functions provide the scheduler implementation
// interface to the Cyg_Scheduler class. These are protected
// so that only the scheduler can call them.
// choose a new thread
Cyg_Thread *schedule();
// make thread schedulable
void add_thread(Cyg_Thread *thread);
// make thread un-schedulable
void rem_thread(Cyg_Thread *thread);
// register thread with scheduler
void register_thread(Cyg_Thread *thread);
// deregister thread
void deregister_thread(Cyg_Thread *thread);
// Test the given priority for uniqueness
cyg_bool unique( cyg_priority priority);
// Set need_reschedule if the supplied thread is of lower
// priority than any that are currently running.
static void set_need_reschedule( Cyg_Thread *thread );
static void set_need_reschedule();
public:
void set_idle_thread( Cyg_Thread *thread, HAL_SMP_CPU_TYPE cpu );
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
// If timeslicing is enbled, define a scheduler
// entry points to do timeslicing. This will be
// called from the RTC DSR.
public:
void timeslice();
void timeslice_cpu();
#endif
};
// -------------------------------------------------------------------------
// Cyg_Scheduler_Implementation inlines
inline void Cyg_Scheduler_Implementation::set_need_reschedule()
{
need_reschedule[CYG_KERNEL_CPU_THIS()] = true;
}
// -------------------------------------------------------------------------
// Scheduler thread implementation.
// This class provides the implementation of the scheduler specific parts
// of each thread.
class Cyg_SchedThread_Implementation
: public Cyg_DNode_T<Cyg_Thread>
{
friend class Cyg_Scheduler_Implementation;
friend class Cyg_ThreadQueue_Implementation;
protected:
cyg_priority priority; // current thread priority
#ifdef CYGPKG_KERNEL_SMP_SUPPORT
HAL_SMP_CPU_TYPE cpu; // CPU id of cpu currently running
// this thread, or CYG_KERNEL_CPU_NONE
// if not running.
#endif
Cyg_SchedThread_Implementation(CYG_ADDRWORD sched_info);
void yield(); // Yield CPU to next thread
static void rotate_queue( cyg_priority pri );
// Rotate that run queue
void to_queue_head( void ); // Move this thread to the head
// of its queue (not necessarily
// a scheduler queue)
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
cyg_ucount32 timeslice_count;
void timeslice_save();
void timeslice_restore();
void timeslice_reset();
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
// This defines whether this thread is subject to timeslicing.
// If false, timeslice expiry has no effect on the thread.
cyg_bool timeslice_enabled;
public:
void timeslice_enable();
void timeslice_disable();
#endif
#else
inline void timeslice_save() {};
inline void timeslice_restore() {};
inline void timeslice_reset() {};
#endif
};
// -------------------------------------------------------------------------
// Cyg_SchedThread_Implementation inlines.
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
inline void Cyg_SchedThread_Implementation::timeslice_save()
{
timeslice_count = Cyg_Scheduler_Implementation::timeslice_count[CYG_KERNEL_CPU_THIS()];
}
inline void Cyg_SchedThread_Implementation::timeslice_restore()
{
Cyg_Scheduler_Implementation::timeslice_count[CYG_KERNEL_CPU_THIS()] = timeslice_count;
}
inline void Cyg_SchedThread_Implementation::timeslice_reset()
{
timeslice_count = CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS;
}
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
inline void Cyg_SchedThread_Implementation::timeslice_enable()
{
timeslice_enabled = true;
}
inline void Cyg_SchedThread_Implementation::timeslice_disable()
{
timeslice_enabled = false;
}
#endif
#endif
// -------------------------------------------------------------------------
#endif // ifndef CYGONCE_KERNEL_MLQUEUE_HXX
// EOF mlqueue.hxx
Go to most recent revision | Compare with Previous | Blame | View Log