diff packages/kernel/current/include/thread.inl @ 147:d397fc472bcf

Merge from eCos master repository on 2001-01-05-06:43:02-GMT
author jlarmour
date Fri, 05 Jan 2001 17:12:36 +0000
parents 6b5f480c6929
children e2d866e32dac
line wrap: on
line diff
--- a/packages/kernel/current/include/thread.inl
+++ b/packages/kernel/current/include/thread.inl
@@ -86,10 +86,10 @@ inline void Cyg_HardwareThread::check_st
     cyg_uint32 sig = (cyg_uint32)this;
     cyg_uint32 *base = (cyg_uint32 *)get_stack_base();
     cyg_uint32 *top =  (cyg_uint32 *)(stack_base + stack_size);
-    unsigned int i;
+    cyg_ucount32 i;
 
-    CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base not word aligned" );
-    CYG_ASSERT( 0 == (3 & (cyg_uint32)top),  "stack  top not word aligned" );
+    CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base not word aligned" );
+    CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top),  "stack  top not word aligned" );
 
     CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base,
                 "Stack_ptr below base" );
@@ -102,6 +102,47 @@ inline void Cyg_HardwareThread::check_st
         CYG_ASSERT( (sig ^ (i * 0x01010101)) == base[i], "Stack base corrupt" );
         CYG_ASSERT( (sig ^ (i * 0x10101010)) ==  top[i], "Stack top corrupt"  );
     }            
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
+    // we won't have added check data above the stack limit if it hasn't
+    // been incremented
+    if (stack_limit != stack_base) {
+        CYG_ADDRESS limit = stack_limit;
+        // the limit will be off by the check data size, so lets correct it
+        limit -= CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
+        
+        // determine base of check data by rounding up to nearest word aligned
+        // address if not already aligned
+        cyg_uint32 *p = (cyg_uint32 *)((limit + 3) & ~3);
+        // i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1);
+        
+        for ( i = 0;
+              i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
+              i++ ) {
+            CYG_ASSERT( (sig ^ (i * 0x01010101)) == p[i],
+                        "Gap between stack limit and base corrupt" );
+        }
+    }
+#endif
+}
+#endif
+
+// -------------------------------------------------------------------------
+// Measure the stack usage of the thread
+#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
+inline cyg_uint32 Cyg_HardwareThread::measure_stack_usage(void)
+{
+    CYG_WORD *base = (CYG_WORD *)stack_base;
+    cyg_uint32 size = stack_size/sizeof(CYG_WORD);
+    cyg_ucount32 i;
+
+    // Work up the stack comparing with the preset value
+    // We assume the stack grows downwards, hmm...
+    for (i=0; i<size; i++) {
+	if (base[i] != 0xDEADBEEF)
+	  break;
+    }
+    return (size - i)*sizeof(CYG_WORD);
 }
 #endif
 
@@ -124,8 +165,8 @@ inline void Cyg_HardwareThread::attach_s
 
         unsigned int i;
 
-        CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base alignment" );
-        CYG_ASSERT( 0 == (3 & (cyg_uint32)top),  "stack  top alignment" );
+        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base alignment" );
+        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top),  "stack  top alignment" );
 
         for ( i = 0;
               i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
@@ -145,7 +186,24 @@ inline void Cyg_HardwareThread::attach_s
                     "Stack size too small after allocating checking buffer");
     }
 #endif
+#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
+    {
+	CYG_WORD *base = (CYG_WORD *)s_base;
+	cyg_uint32 size = s_size/sizeof(CYG_WORD);
+	cyg_ucount32 i;
 
+	// initialize all of stack with known value - don't choose 0
+	// could do with pseudo value as above, but this way, checking
+	// is faster
+	for (i=0; i<size; i++) {
+		base[i] = 0xDEADBEEF;
+	}
+	// Don't bother about the case when the stack isn't a multiple of
+	// CYG_WORD in size. Since it's at the top of the stack, it will
+	// almost certainly be overwritten the instant the thread starts
+	// anyway.
+    }
+#endif
     stack_base = s_base;
     stack_size = s_size;
 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
@@ -269,12 +327,15 @@ inline CYG_ADDRWORD Cyg_HardwareThread::
 
 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
 
-inline void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size)
+#ifndef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+// if stack checking, implementation is in thread.cxx
+inline void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size )
 {
+    void *ret = (void *)stack_limit;
     stack_limit += size;
-    return (void *)(stack_limit - size);
+    return ret;
 }
-
+#endif
     
 inline CYG_ADDRESS
 Cyg_HardwareThread::get_stack_limit()