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
     
 };