Mercurial > flash_v2
diff packages/kernel/current/include/sched.hxx @ 115:6ed91473a1cd ecos-sw-2000-08-21
Merge from eCos master repository on 2000-08-21-22:40:54-BST
| author | jlarmour |
|---|---|
| date | Fri, 25 Aug 2000 17:32:38 +0000 |
| parents | bf00f99aec69 |
| children | 0ec04793409a |
line wrap: on
line diff
--- a/packages/kernel/current/include/sched.hxx +++ b/packages/kernel/current/include/sched.hxx @@ -49,6 +49,16 @@ #include <cyg/kernel/ktypes.h> #include <cyg/infra/cyg_ass.h> // assertion macros + +// ------------------------------------------------------------------------- +// Miscellaneous types + +#ifdef CYGSEM_KERNEL_SCHED_ASR_SUPPORT + +typedef void Cyg_ASR( CYG_ADDRWORD data ); // ASR type signature + +#endif + // ------------------------------------------------------------------------- // Scheduler base class. This defines stuff that is needed by the // specific scheduler implementation. Each scheduler comprises three @@ -81,12 +91,12 @@ protected: // Do some checking that we have a consistent universe. -#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL # ifndef CYGIMP_THREAD_PRIORITY -# error Priority inheritance will not work without priorities!!! +# error Priority inversion protocols will not work without priorities!!! # endif # if CYG_SCHED_UNIQUE_PRIORITIES -# error Priority inheritance needs non-unique priorities!!! +# error Priority inversion protocols need non-unique priorities!!! # endif #endif @@ -103,7 +113,7 @@ class Cyg_Scheduler // function. The unlock() later is an inline shell that deals // with the common case. - static void unlock_inner(); + static void unlock_inner(cyg_uint32 new_lock = 0); public: @@ -118,6 +128,9 @@ public: // release the preemption lock and possibly reschedule static void unlock(); + // release and reclaim the lock atomically + static void reschedule(); + // release the preemption lock without rescheduling static void unlock_simple(); @@ -149,6 +162,7 @@ class Cyg_SchedThread { friend class Cyg_ThreadQueue_Implementation; friend class Cyg_Scheduler_Implementation; + friend class Cyg_Scheduler; Cyg_ThreadQueue *queue; @@ -164,34 +178,111 @@ public: // Remove this thread from current queue void remove(); -#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE +#ifdef CYGSEM_KERNEL_SCHED_ASR_SUPPORT + + // ASR support. + // An ASR is an Asynchronous Service Routine. When set pending it + // is called when the thread exits the scheduler. ASRs are mainly + // used by compatibility subsystems, such as POSIX, to implement + // such things as thread cancellation and signal delivery. private: - // For all priority inheritance mechanisms we need to keep track of how + volatile cyg_bool asr_inhibit; // If true, blocks calls to ASRs + + volatile cyg_bool asr_pending; // If true, this thread's ASR should be called. + +#ifdef CYGSEM_KERNEL_SCHED_ASR_GLOBAL + static +#endif + Cyg_ASR *asr; // ASR function +#ifdef CYGSEM_KERNEL_SCHED_ASR_DATA_GLOBAL + static +#endif + CYG_ADDRWORD asr_data; // ASR data pointer + + // Default ASR function + static void asr_default(CYG_ADDRWORD data); + +public: + + // Public interface to ASR mechanism + + // Set, clear and get inhibit flag. + inline void set_asr_inhibit() { asr_inhibit = true; } + inline void clear_asr_inhibit() { asr_inhibit = false; } + inline cyg_bool get_asr_inhibit() { return asr_inhibit; } + + // Set and get pending flag. The flag is only cleared when the + // ASR is called. + inline void set_asr_pending() { asr_pending = true; } + inline cyg_bool get_asr_pending() { return asr_pending; } + + // Set a new ASR, returning the old one. + void set_asr( Cyg_ASR *new_asr, CYG_ADDRWORD new_data, + Cyg_ASR **old_asr, CYG_ADDRWORD *old_data); + + // Clear the ASR function back to the default. + void clear_asr(); + +#else + +public: + + // Even when we do not have ASRs enabled, we keep these functions + // available. This avoids excessive ifdefs in the rest of the + // kernel code. + inline void set_asr_inhibit() { } + inline void clear_asr_inhibit() { } + +#endif + +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL + +private: + + // For all priority inversion protocols we need to keep track of how // many mutexes we have locked, including one which we are waiting to // lock, because we can inherit priority while sleeping just prior to // wakeup. + cyg_count32 mutex_count; +protected: + // These are implementation functions that are common to all protocols. + + // Inherit the given priority. If thread is non-NULL the priority is + // being inherited from it, otherwise it has come from the mutex. + void set_inherited_priority( cyg_priority pri, Cyg_Thread *thread = 0 ); + + // Relay the priority of the ex-owner thread or from the queue if it + // has a higher priority than ours. + void relay_inherited_priority( Cyg_Thread *ex_owner, Cyg_ThreadQueue *pqueue); + + // Lose priority inheritance + void clear_inherited_priority(); + public: // Count and uncount the number of mutexes held by // this thread. void count_mutex() { mutex_count++; }; void uncount_mutex() { mutex_count--; }; + +#if defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_SIMPLE) protected: -#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE - // The simple priority inheritance mechanism simply needs + // The simple priority inversion protocols simply needs // somewhere to store the base priority of the current thread. cyg_priority original_priority; // our original priority cyg_bool priority_inherited; // have we inherited? - + #endif +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT + public: // Inherit the priority of the provided thread if it @@ -206,6 +297,20 @@ public: void disinherit_priority(); #endif + +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING + +public: + + // Set the priority of this thread to the given ceiling. + void set_priority_ceiling( cyg_priority pri ); + + // Clear the ceiling, if necessary. + void clear_priority_ceiling(); + +#endif + +#endif };
