]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/kernel/v2_0/include/mlqueue.hxx
Initial revision
[karo-tx-redboot.git] / packages / kernel / v2_0 / include / mlqueue.hxx
1 #ifndef CYGONCE_KERNEL_MLQUEUE_HXX
2 #define CYGONCE_KERNEL_MLQUEUE_HXX
3
4 //==========================================================================
5 //
6 //      mlqueue.hxx
7 //
8 //      Multi-Level Queue scheduler class declarations
9 //
10 //==========================================================================
11 //####ECOSGPLCOPYRIGHTBEGIN####
12 // -------------------------------------------
13 // This file is part of eCos, the Embedded Configurable Operating System.
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15 //
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
19 //
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 // for more details.
24 //
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 //
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
35 //
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
38 //
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //==========================================================================
44 //#####DESCRIPTIONBEGIN####
45 //
46 // Author(s):    nickg
47 // Contributors: jlarmour
48 // Date:         1997-09-10
49 // Purpose:      Define multilevel queue scheduler implementation
50 // Description:  The classes defined here are used as base classes
51 //               by the common classes that define schedulers and thread
52 //               things. The MLQ scheduler in various configurations
53 //               provides standard FIFO, round-robin and single priority
54 //               schedulers.
55 // Usage:        Included according to configuration by
56 //               <cyg/kernel/sched.hxx>
57 //
58 //####DESCRIPTIONEND####
59 //
60 //==========================================================================
61
62 #include <cyg/kernel/ktypes.h>
63
64 #include <cyg/infra/clist.hxx>                  // List implementation
65
66 // -------------------------------------------------------------------------
67 // The macro CYGNUM_KERNEL_SCHED_PRIORITIES contains the number of priorities
68 // supported by the scheduler.
69
70 #ifndef CYGNUM_KERNEL_SCHED_PRIORITIES
71 #define CYGNUM_KERNEL_SCHED_PRIORITIES 32       // define a default
72 #endif
73
74 // set bitmap size
75 #define CYGNUM_KERNEL_SCHED_BITMAP_SIZE CYGNUM_KERNEL_SCHED_PRIORITIES
76
77 // -------------------------------------------------------------------------
78 // The macro CYGNUM_KERNEL_SCHED_BITMAP_SIZE contains the number of bits that the
79 // scheduler bitmap should contain. It is derived from the number of prioirity
80 // levels defined by the configuration.
81
82 #if CYGNUM_KERNEL_SCHED_BITMAP_SIZE <= 8
83 typedef cyg_ucount8 cyg_sched_bitmap;
84 #elif CYGNUM_KERNEL_SCHED_BITMAP_SIZE <= 16
85 typedef cyg_ucount16 cyg_sched_bitmap;
86 #elif CYGNUM_KERNEL_SCHED_BITMAP_SIZE <= 32
87 typedef cyg_ucount32 cyg_sched_bitmap;
88 #else
89 #error Bitmaps greater than 32 bits not currently allowed
90 #endif
91
92 // -------------------------------------------------------------------------
93 // Customize the scheduler
94
95 #define CYGIMP_THREAD_PRIORITY  1       // Threads have changable priorities
96
97 #define CYG_THREAD_MIN_PRIORITY (CYGNUM_KERNEL_SCHED_PRIORITIES-1)
98 #define CYG_THREAD_MAX_PRIORITY 0
99
100 // set default scheduling info value for thread constructors.
101 #define CYG_SCHED_DEFAULT_INFO  CYG_THREAD_MAX_PRIORITY
102
103 // -------------------------------------------------------------------------
104 // scheduler Run queue object
105
106 typedef Cyg_CList_T<Cyg_Thread> Cyg_RunQueue;
107
108 // -------------------------------------------------------------------------
109 // Thread queue implementation.
110 // This class provides the (scheduler specific) implementation of the
111 // thread queue class.
112
113 class Cyg_ThreadQueue_Implementation
114     : public Cyg_CList_T<Cyg_Thread>
115 {
116     friend class Cyg_Scheduler_Implementation;
117     friend class Cyg_SchedThread_Implementation;
118
119     void                set_thread_queue(Cyg_Thread *thread,
120                                          Cyg_ThreadQueue *tq );
121
122 protected:
123
124     // API used by Cyg_ThreadQueue
125
126     Cyg_ThreadQueue_Implementation() {};   // Constructor
127     
128                                         // Add thread to queue
129     void                enqueue(Cyg_Thread *thread);
130
131                                         // return first thread on queue
132     Cyg_Thread          *highpri();
133
134                                         // remove first thread on queue    
135     Cyg_Thread          *dequeue();
136
137                                         // Remove thread from queue
138     void                remove(Cyg_Thread *thread);
139
140 };
141
142 // -------------------------------------------------------------------------
143 // This class contains the implementation details of the scheduler, and
144 // provides a standard API for accessing it.
145
146 class Cyg_Scheduler_Implementation
147     : public Cyg_Scheduler_Base
148 {
149     friend class Cyg_ThreadQueue_Implementation;
150     friend class Cyg_SchedThread_Implementation;
151     friend class Cyg_HardwareThread;
152     friend void cyg_scheduler_set_need_reschedule();
153     
154     // Mask of which run queues have ready threads
155     cyg_sched_bitmap    queue_map;
156
157     // Each run queue is a double linked circular list of threads.
158     // These pointers point to the head element of each list.
159     Cyg_RunQueue run_queue[CYGNUM_KERNEL_SCHED_PRIORITIES];
160
161 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
162
163     // In SMP systems we additionally keep a counter for each priority
164     // of the number of pending but not running threads in each queue.
165     
166     cyg_uint32 pending[CYGNUM_KERNEL_SCHED_PRIORITIES];
167
168     cyg_sched_bitmap pending_map;
169
170 #endif    
171
172 protected:
173     
174 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
175
176     // Timeslice counter. This is decremented on each
177     // clock tick, and a timeslice is performed each
178     // time it zeroes.
179     
180     static cyg_ucount32 timeslice_count[CYGNUM_KERNEL_CPU_MAX]
181                                         CYGBLD_ANNOTATE_VARIABLE_SCHED;
182
183     static void reset_timeslice_count();
184
185 #endif
186
187     Cyg_Scheduler_Implementation();     // Constructor
188     
189     // The following functions provide the scheduler implementation
190     // interface to the Cyg_Scheduler class. These are protected
191     // so that only the scheduler can call them.
192     
193     // choose a new thread
194     Cyg_Thread  *schedule();
195
196     // make thread schedulable
197     void        add_thread(Cyg_Thread *thread);
198
199     // make thread un-schedulable
200     void        rem_thread(Cyg_Thread *thread);
201
202     // register thread with scheduler
203     void        register_thread(Cyg_Thread *thread);
204
205     // deregister thread
206     void        deregister_thread(Cyg_Thread *thread);
207     
208     // Test the given priority for uniqueness
209     cyg_bool    unique( cyg_priority priority);
210
211     // Set need_reschedule if the supplied thread is of lower
212     // priority than any that are currently running.
213     static void set_need_reschedule( Cyg_Thread *thread );
214     static void set_need_reschedule();
215
216 public:
217     void set_idle_thread( Cyg_Thread *thread, HAL_SMP_CPU_TYPE cpu );
218     
219 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
220
221     // If timeslicing is enbled, define a scheduler
222     // entry points to do timeslicing. This will be
223     // called from the RTC DSR.
224 public:    
225     void timeslice();
226     void timeslice_cpu();
227
228 #endif
229
230 };
231
232 // -------------------------------------------------------------------------
233 // Cyg_Scheduler_Implementation inlines
234
235 inline void Cyg_Scheduler_Implementation::set_need_reschedule()
236 {
237     need_reschedule[CYG_KERNEL_CPU_THIS()] = true;
238 }
239
240 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
241
242 inline void Cyg_Scheduler_Implementation::reset_timeslice_count()
243 {
244     timeslice_count[CYG_KERNEL_CPU_THIS()] = CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS;
245 }
246
247 #endif
248
249 // -------------------------------------------------------------------------
250 // Scheduler thread implementation.
251 // This class provides the implementation of the scheduler specific parts
252 // of each thread.
253
254 class Cyg_SchedThread_Implementation
255     : public Cyg_DNode_T<Cyg_Thread>
256 {
257     friend class Cyg_Scheduler_Implementation;
258     friend class Cyg_ThreadQueue_Implementation;
259
260 protected:
261
262     cyg_priority        priority;       // current thread priority
263
264 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
265     HAL_SMP_CPU_TYPE    cpu;            // CPU id of cpu currently running
266                                         // this thread, or CYG_KERNEL_CPU_NONE
267                                         // if not running.
268 #endif
269     
270     Cyg_SchedThread_Implementation(CYG_ADDRWORD sched_info);
271
272     void yield();                       // Yield CPU to next thread
273
274     static void rotate_queue( cyg_priority pri );
275                                         // Rotate that run queue
276
277     void to_queue_head( void );         // Move this thread to the head
278                                         // of its queue (not necessarily
279                                         // a scheduler queue)
280
281 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
282
283     // This defines whether this thread is subject to timeslicing.
284     // If false, timeslice expiry has no effect on the thread.
285     
286     cyg_bool            timeslice_enabled;
287
288 public:
289     
290     void timeslice_enable();
291
292     void timeslice_disable();
293     
294 #endif    
295        
296 };
297
298 // -------------------------------------------------------------------------
299 // Cyg_SchedThread_Implementation inlines.
300
301 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
302
303 inline void Cyg_SchedThread_Implementation::timeslice_enable()
304 {
305     timeslice_enabled = true;
306 }
307
308 inline void Cyg_SchedThread_Implementation::timeslice_disable()
309 {
310     timeslice_enabled = false;
311 }
312
313 #endif
314
315
316 // -------------------------------------------------------------------------
317 #endif // ifndef CYGONCE_KERNEL_MLQUEUE_HXX
318 // EOF mlqueue.hxx