OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [include/] [sched.hxx] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#ifndef CYGONCE_KERNEL_SCHED_HXX
2
#define CYGONCE_KERNEL_SCHED_HXX
3
 
4
//==========================================================================
5
//
6
//      sched.hxx
7
//
8
//      Scheduler class declaration(s)
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 Free Software Foundation, 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
19
// version.
20
//
21
// eCos is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License
27
// along with eCos; if not, write to the Free Software Foundation, Inc.,
28
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
29
//
30
// As a special exception, if other files instantiate templates or use
31
// macros or inline functions from this file, or you compile this file
32
// and link it with other works to produce a work based on this file,
33
// this file does not by itself cause the resulting work to be covered by
34
// the GNU General Public License. However the source code for this file
35
// must still be made available in accordance with section (3) of the GNU
36
// General Public License v2.
37
//
38
// This exception does not invalidate any other reasons why a work based
39
// on this file might be covered by the GNU General Public License.
40
// -------------------------------------------
41
// ####ECOSGPLCOPYRIGHTEND####
42
//==========================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):   nickg
46
// Contributors:        nickg
47
// Date:        1997-09-09
48
// Purpose:     Define Scheduler class interfaces
49
// Description: These class definitions supply the internal API
50
//              used to scheduler threads.
51
// Usage:       #include 
52
//
53
//####DESCRIPTIONEND####
54
//
55
//==========================================================================
56
 
57
#include 
58
#include          // assertion macros
59
 
60
#include           // SMP support
61
 
62
// -------------------------------------------------------------------------
63
// Miscellaneous types
64
 
65
#ifdef CYGSEM_KERNEL_SCHED_ASR_SUPPORT
66
 
67
typedef void Cyg_ASR( CYG_ADDRWORD data );      // ASR type signature
68
 
69
#endif
70
 
71
__externC void cyg_scheduler_set_need_reschedule();
72
 
73
// -------------------------------------------------------------------------
74
// Scheduler base class. This defines stuff that is needed by the
75
// specific scheduler implementation. Each scheduler comprises three
76
// classes: Cyg_Scheduler_Base, Cyg_Scheduler_Implementation which
77
// inherits from it and Cyg_Scheduler which inherits from _it_ in turn.
78
 
79
class Cyg_Scheduler_Base
80
     : public Cyg_Scheduler_SchedLock
81
{
82
    friend class Cyg_HardwareThread;
83
    friend class Cyg_SchedThread;
84
 
85
protected:
86
    // The following variables are implicit in the API, but are
87
    // not publically visible.
88
 
89
    // Current running thread
90
    static Cyg_Thread * volatile current_thread[CYGNUM_KERNEL_CPU_MAX]
91
                                                CYGBLD_ANNOTATE_VARIABLE_SCHED;
92
 
93
    // Set when reschedule needed
94
    static volatile cyg_bool     need_reschedule[CYGNUM_KERNEL_CPU_MAX]
95
                                                 CYGBLD_ANNOTATE_VARIABLE_SCHED;
96
 
97
    // Count of number of thread switches
98
    static volatile cyg_ucount32 thread_switches[CYGNUM_KERNEL_CPU_MAX]
99
                                                 CYGBLD_ANNOTATE_VARIABLE_SCHED;
100
 
101
public:
102
 
103
    // return a pointer to the current thread
104
    static Cyg_Thread *get_current_thread();
105
 
106
    // Set current thread pointer
107
    static void set_current_thread(Cyg_Thread *thread);
108
    static void set_current_thread(Cyg_Thread *thread, HAL_SMP_CPU_TYPE cpu);
109
 
110
    // Set need_reschedule flag
111
    static void set_need_reschedule();
112
    static void set_need_reschedule(Cyg_Thread *thread);
113
 
114
    // Get need_reschedule flag
115
    static cyg_bool get_need_reschedule();
116
 
117
    // Return current value of lock
118
    static cyg_ucount32 get_sched_lock();
119
 
120
    // Clear need_reschedule flag
121
    static void clear_need_reschedule();
122
 
123
    // Return current number of thread switches
124
    static cyg_ucount32 get_thread_switches();
125
 
126
};
127
 
128
// -------------------------------------------------------------------------
129
// Include the scheduler implementation header
130
 
131
#include CYGPRI_KERNEL_SCHED_IMPL_HXX
132
 
133
// Do some checking that we have a consistent universe.
134
 
135
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL
136
# ifndef CYGIMP_THREAD_PRIORITY
137
#  error Priority inversion protocols will not work without priorities!!!
138
# endif
139
#endif
140
 
141
// -------------------------------------------------------------------------
142
// Scheduler class. This is the public scheduler interface seen by the
143
// rest of the kernel.
144
 
145
class Cyg_Scheduler
146
    : public Cyg_Scheduler_Implementation
147
{
148
    friend class Cyg_Thread;
149
 
150
    // This function is the actual implementation of the unlock
151
    // function.  The unlock() later is an inline shell that deals
152
    // with the common case.
153
 
154
    static void             unlock_inner(cyg_uint32 new_lock = 0);
155
 
156
public:
157
 
158
    CYGDBG_DEFINE_CHECK_THIS
159
 
160
    // The following API functions are common to all scheduler
161
    // implementations.
162
 
163
    // claim the preemption lock
164
    static void             lock();
165
 
166
    // release the preemption lock and possibly reschedule
167
    static void             unlock();
168
 
169
    // release and reclaim the lock atomically, keeping the old
170
    // value on restart
171
    static void             reschedule();
172
 
173
    // decrement the lock but also look for a reschedule opportunity
174
    static void             unlock_reschedule();
175
 
176
    // release the preemption lock without rescheduling
177
    static void             unlock_simple();
178
 
179
    // perform thread startup housekeeping
180
    void thread_entry( Cyg_Thread *thread );
181
 
182
    // Start execution of the scheduler
183
    static void start() CYGBLD_ATTRIB_NORET;
184
 
185
    // Start execution of the scheduler on the current CPU
186
    static void start_cpu() CYGBLD_ATTRIB_NORET;
187
 
188
    // The only  scheduler instance should be this one...
189
    static Cyg_Scheduler scheduler CYGBLD_ANNOTATE_VARIABLE_SCHED;
190
 
191
};
192
 
193
// -------------------------------------------------------------------------
194
// This class encapsulates the scheduling abstractions in a thread.
195
// Cyg_SchedThread is included as a base class of Cyg_Thread. The actual
196
// implementation of the abstractions is in Cyg_SchedThread_Implementation
197
// so this class has little to do.
198
 
199
class Cyg_SchedThread
200
    : public Cyg_SchedThread_Implementation
201
{
202
    friend class Cyg_ThreadQueue_Implementation;
203
    friend class Cyg_Scheduler_Implementation;
204
    friend class Cyg_Scheduler;
205
 
206
    Cyg_ThreadQueue     *queue;
207
 
208
 
209
public:
210
 
211
    Cyg_SchedThread(Cyg_Thread *thread, CYG_ADDRWORD sched_info);
212
 
213
    // Return current queue pointer
214
 
215
    Cyg_ThreadQueue     *get_current_queue();
216
 
217
    // Remove this thread from current queue
218
    void remove();
219
 
220
#ifdef CYGSEM_KERNEL_SCHED_ASR_SUPPORT
221
 
222
    // ASR support.
223
    // An ASR is an Asynchronous Service Routine. When set pending it
224
    // is called when the thread exits the scheduler. ASRs are mainly
225
    // used by compatibility subsystems, such as POSIX, to implement
226
    // such things as thread cancellation and signal delivery.
227
 
228
private:
229
 
230
    volatile cyg_ucount32       asr_inhibit;    // If > 0, blocks calls to ASRs
231
 
232
    volatile cyg_bool           asr_pending;    // If true, this thread's ASR should be called.
233
 
234
#ifdef CYGSEM_KERNEL_SCHED_ASR_GLOBAL
235
    static
236
#endif
237
    Cyg_ASR             *asr;            // ASR function
238
#ifdef CYGSEM_KERNEL_SCHED_ASR_DATA_GLOBAL
239
    static
240
#endif
241
    CYG_ADDRWORD        asr_data;       // ASR data pointer
242
 
243
    // Default ASR function
244
    static void         asr_default(CYG_ADDRWORD data);
245
 
246
public:
247
 
248
    // Public interface to ASR mechanism
249
 
250
    // Set, clear and get inhibit flag.
251
    inline void set_asr_inhibit() { asr_inhibit++; }
252
    inline void clear_asr_inhibit() { asr_inhibit--; }
253
    inline cyg_ucount32 get_asr_inhibit() { return asr_inhibit; }
254
 
255
    // Set and get pending flag. The flag is only cleared when the
256
    // ASR is called.
257
    inline void set_asr_pending() { asr_pending = true; }
258
    inline cyg_bool get_asr_pending() { return asr_pending; }
259
 
260
    // Set a new ASR, returning the old one.
261
    void set_asr( Cyg_ASR  *new_asr, CYG_ADDRWORD  new_data,
262
                  Cyg_ASR **old_asr, CYG_ADDRWORD *old_data);
263
 
264
    // Clear the ASR function back to the default.
265
    void clear_asr();
266
 
267
#else
268
 
269
public:
270
 
271
    // Even when we do not have ASRs enabled, we keep these functions
272
    // available. This avoids excessive ifdefs in the rest of the
273
    // kernel code.
274
    inline void set_asr_inhibit() { }
275
    inline void clear_asr_inhibit() { }
276
 
277
#endif
278
 
279
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL
280
 
281
private:
282
 
283
    // For all priority inversion protocols we need to keep track of how
284
    // many mutexes we have locked, including one which we are waiting to
285
    // lock, because we can inherit priority while sleeping just prior to
286
    // wakeup.
287
 
288
    cyg_count32         mutex_count;
289
 
290
protected:
291
    // These are implementation functions that are common to all protocols.
292
 
293
    // Inherit the given priority. If thread is non-NULL the priority is
294
    // being inherited from it, otherwise it has come from the mutex.
295
    void set_inherited_priority( cyg_priority pri, Cyg_Thread *thread = 0 );
296
 
297
    // Relay the priority of the ex-owner thread or from the queue if it
298
    // has a higher priority than ours.
299
    void relay_inherited_priority( Cyg_Thread *ex_owner, Cyg_ThreadQueue *pqueue);
300
 
301
    // Lose priority inheritance
302
    void clear_inherited_priority();
303
 
304
public:
305
    // Count and uncount the number of mutexes held by
306
    // this thread.
307
    void count_mutex() { mutex_count++; };
308
    void uncount_mutex() { mutex_count--; };
309
 
310
#if defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_SIMPLE)
311
 
312
protected:
313
 
314
    // The simple priority inversion protocols simply needs
315
    // somewhere to store the base priority of the current thread.
316
 
317
    cyg_priority        original_priority;      // our original priority
318
 
319
    cyg_bool            priority_inherited;     // have we inherited?
320
 
321
#endif
322
 
323
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
324
 
325
public:
326
 
327
    // Inherit the priority of the provided thread if it
328
    // has higher priority than this.
329
    void inherit_priority( Cyg_Thread *thread);
330
 
331
    // Relay the priority of the ex-owner thread or from the queue if it
332
    // has a higher priority than ours.
333
    void relay_priority( Cyg_Thread *ex_owner, Cyg_ThreadQueue *pqueue);
334
 
335
    // Lose priority inheritance
336
    void disinherit_priority();
337
 
338
#endif
339
 
340
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
341
 
342
public:
343
 
344
    // Set the priority of this thread to the given ceiling.
345
    void set_priority_ceiling( cyg_priority pri );
346
 
347
    // Clear the ceiling, if necessary.
348
    void clear_priority_ceiling();
349
 
350
#endif
351
 
352
#endif
353
 
354
};
355
 
356
// -------------------------------------------------------------------------
357
// Simple inline accessor functions
358
 
359
inline Cyg_Thread *Cyg_Scheduler_Base::get_current_thread()
360
{
361
    return current_thread[CYG_KERNEL_CPU_THIS()];
362
}
363
 
364
inline void Cyg_Scheduler_Base::set_current_thread(Cyg_Thread *thread )
365
{
366
    current_thread[CYG_KERNEL_CPU_THIS()] = thread;
367
}
368
 
369
inline void Cyg_Scheduler_Base::set_current_thread(Cyg_Thread *thread,
370
                                                   HAL_SMP_CPU_TYPE cpu)
371
{
372
    current_thread[cpu] = thread;
373
}
374
 
375
inline cyg_bool Cyg_Scheduler_Base::get_need_reschedule()
376
{
377
    return need_reschedule[CYG_KERNEL_CPU_THIS()];
378
}
379
 
380
inline void Cyg_Scheduler_Base::set_need_reschedule()
381
{
382
    need_reschedule[CYG_KERNEL_CPU_THIS()] = true;
383
}
384
 
385
inline void Cyg_Scheduler_Base::set_need_reschedule(Cyg_Thread *thread)
386
{
387
    need_reschedule[CYG_KERNEL_CPU_THIS()] = true;
388
}
389
 
390
inline void Cyg_Scheduler_Base::clear_need_reschedule()
391
{
392
    need_reschedule[CYG_KERNEL_CPU_THIS()] = false;
393
}
394
 
395
inline cyg_ucount32 Cyg_Scheduler_Base::get_sched_lock()
396
{
397
    return Cyg_Scheduler_SchedLock::get_sched_lock();
398
}
399
 
400
// Return current number of thread switches
401
inline cyg_ucount32 Cyg_Scheduler_Base::get_thread_switches()
402
{
403
    return thread_switches[CYG_KERNEL_CPU_THIS()];
404
}
405
 
406
// Return current queue pointer
407
inline Cyg_ThreadQueue *Cyg_SchedThread::get_current_queue()
408
{
409
    return queue;
410
}
411
 
412
// -------------------------------------------------------------------------
413
#endif // ifndef __SCHED_HXX__
414
// EOF sched.hxx

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.