changeset 3025:1bb791eebd38

Merge from anoncvs
author Ross Younger <wry@ecoscentric.com>
date Fri, 14 May 2010 16:55:25 +0100
parents 38db370fd99b (current diff) ae816c83f082 (diff)
children a9d12f1a0c5b
files
diffstat 10 files changed, 319 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-29  Lars Povlsen  <lpovlsen@vitesse.com>
+
+	* src/common/thread.cxx: Add volatile to idle_thread_loops for use with
+	cpuload package and GCC 4.
+
 2010-02-25  John Dallaway  <john@dallaway.org.uk>
 
 	* doc/kernel.sgml: Indicate that cyg_alarm_initialize() takes an
--- a/packages/kernel/current/src/common/thread.cxx
+++ b/packages/kernel/current/src/common/thread.cxx
@@ -1211,7 +1211,7 @@ Cyg_ThreadTimer::alarm(
 #endif // CYGNUM_HAL_STACK_SIZE_MINIMUM
 
 // Loop counter for debugging/housekeeping
-cyg_uint32 idle_thread_loops[CYGNUM_KERNEL_CPU_MAX];
+cyg_uint32 volatile idle_thread_loops[CYGNUM_KERNEL_CPU_MAX];
 
 static char idle_thread_stack[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE];
 
--- a/packages/language/c/libc/string/current/ChangeLog
+++ b/packages/language/c/libc/string/current/ChangeLog
@@ -1,3 +1,12 @@
+2010-05-10  Ross Younger  <wry@ecoscentric.com>
+
+	* include/string.h: Declare strnlen.
+	* include/stringsupp.hxx: Declare __strnlen.
+	* src/strnlen.cxx, tests/strnlen.c: Created.
+	* cdl/string.cdl (CYGFUN_LIBC_STRING_GNU_STRNLEN): New option,
+	compiles strnlen.cxx.
+	(CYGPKG_LIBC_STRING_TESTS): Add strnlen test.
+
 2009-01-26  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* tests/memchr.c (main): Rename to cyg_user_start if main isn't
--- a/packages/language/c/libc/string/current/cdl/string.cdl
+++ b/packages/language/c/libc/string/current/cdl/string.cdl
@@ -166,6 +166,16 @@ cdl_package CYGPKG_LIBC_STRING {
                 This option indicates whether strdup() is to be supported."
     }
 
+    cdl_option CYGFUN_LIBC_STRING_GNU_STRNLEN {
+        display       "Provide strnlen() GNU extension"
+        flavor        bool
+        default_value 1
+        compile       strnlen.cxx
+        description   "
+            This option controls support for the strnlen() function.
+            (This is a GNU extension, not part of ANSI C.)"
+    }
+
     cdl_component CYGPKG_LIBC_STRING_OPTIONS {
         display "C library string functions build options"
         flavor  none
@@ -202,7 +212,7 @@ cdl_package CYGPKG_LIBC_STRING {
             display "C library string function tests"
             flavor  data
             no_define
-            calculated { "tests/memchr tests/memcmp1 tests/memcmp2 tests/memcpy1 tests/memcpy2 tests/memmove1 tests/memmove2 tests/memset tests/strcat1 tests/strcat2 tests/strchr tests/strcmp1 tests/strcmp2 tests/strcoll1 tests/strcoll2 tests/strcpy1 tests/strcpy2 tests/strcspn tests/strcspn tests/strlen tests/strncat1 tests/strncat2 tests/strncpy1 tests/strncpy2 tests/strpbrk tests/strrchr tests/strspn tests/strstr tests/strtok tests/strxfrm1 tests/strxfrm2" }
+            calculated { "tests/memchr tests/memcmp1 tests/memcmp2 tests/memcpy1 tests/memcpy2 tests/memmove1 tests/memmove2 tests/memset tests/strcat1 tests/strcat2 tests/strchr tests/strcmp1 tests/strcmp2 tests/strcoll1 tests/strcoll2 tests/strcpy1 tests/strcpy2 tests/strcspn tests/strcspn tests/strlen tests/strncat1 tests/strncat2 tests/strncpy1 tests/strncpy2 tests/strpbrk tests/strrchr tests/strspn tests/strstr tests/strtok tests/strxfrm1 tests/strxfrm2 tests/strnlen" }
             description   "
                 This option specifies the set of tests for the C library
                 string functions."
--- a/packages/language/c/libc/string/current/include/string.h
+++ b/packages/language/c/libc/string/current/include/string.h
@@ -155,6 +155,14 @@ extern char *
 strdup( const char * );
 #endif
 
+// This is a GNU extension
+#ifndef __STRICT_ANSI__
+# ifdef CYGFUN_LIBC_STRING_GNU_STRNLEN
+extern size_t
+strnlen( const char *, size_t );
+# endif
+#endif
+
 #ifdef __cplusplus
 }   /* extern "C" */
 #endif
--- a/packages/language/c/libc/string/current/include/stringsupp.hxx
+++ b/packages/language/c/libc/string/current/include/stringsupp.hxx
@@ -212,6 +212,14 @@
 __externC char *
 __strdup( const char * );
 
+// NB This is a GNU extension
+#ifndef __STRICT_ANSI__
+# ifdef CYGFUN_LIBC_STRING_GNU_STRNLEN
+__externC size_t
+__strnlen( const char *, size_t );
+# endif
+#endif
+
 #endif // CYGONCE_LIBC_STRING_STRINGSUPP_HXX multiple inclusion protection
 
 // EOF stringsupp.hxx
new file mode 100644
--- /dev/null
+++ b/packages/language/c/libc/string/current/src/strnlen.cxx
@@ -0,0 +1,134 @@
+//===========================================================================
+//
+//      strnlen.cxx
+//
+//      GNU extension strnlen() routine
+//
+//===========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 1998-2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jlarmour, wry
+// Contributors: 
+// Date:         2010-05-10
+// Purpose:     
+// Description: 
+// Usage:       
+// Note:         Derivative work of strlen.cxx.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/libc_string.h>   // Configuration header
+
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h>    // Common type definitions
+#include <cyg/infra/cyg_trac.h>    // Tracing support
+#include <cyg/infra/cyg_ass.h>     // Assertion support
+#include <string.h>                // Header for this file
+#include <stddef.h>         // Compiler definitions such as size_t, NULL etc.
+#include <cyg/libc/string/stringsupp.hxx> // Useful string function support and
+                                          // prototypes
+
+// EXPORTED SYMBOLS
+
+externC size_t
+strnlen( const char *s , size_t maxlen ) CYGBLD_ATTRIB_WEAK_ALIAS(__strnlen);
+
+// FUNCTIONS
+
+size_t
+__strnlen( const char *s , size_t maxlen )
+{
+    int retval;
+    
+    CYG_REPORT_FUNCNAMETYPE( "__strnlen", "returning length %d" );
+    CYG_REPORT_FUNCARG1( "s=%08x", s );
+
+    CYG_CHECK_DATA_PTR( s, "s is not a valid pointer!" );
+
+#if defined(CYGIMP_LIBC_STRING_PREFER_SMALL_TO_FAST) || defined(__OPTIMIZE_SIZE__)
+    const char *start = s;
+    
+    while (*s && maxlen)
+        s++, maxlen--;
+    
+    retval = s - start;
+
+    CYG_REPORT_RETVAL( retval );
+
+    return retval;
+
+#else
+
+    const char *start = s;
+    CYG_WORD *aligned_addr;
+    
+    if (CYG_LIBC_STR_UNALIGNED (s))
+    {
+        while (*s && maxlen)
+            s++, maxlen--;
+        retval = s - start;
+
+        CYG_REPORT_RETVAL( retval );
+    
+        return retval;
+    }
+    
+    // If the string is word-aligned, we can check for the presence of 
+    // a null in each word-sized block.
+    
+    aligned_addr = (CYG_WORD *)s;
+    while (!CYG_LIBC_STR_DETECTNULL (*aligned_addr) && (maxlen>= sizeof(CYG_WORD)))
+        aligned_addr++, maxlen -= sizeof(CYG_WORD);
+    
+    // Once a null is detected, we check each byte in that block for a
+    // precise position of the null.
+    s = (char*)aligned_addr; 
+    while (*s && maxlen)
+        s++, maxlen--;
+    retval = s - start;
+
+    CYG_REPORT_RETVAL( retval );
+    
+    return retval;
+#endif // not defined(CYGIMP_LIBC_STRING_PREFER_SMALL_TO_FAST) ||
+       //     defined(__OPTIMIZE_SIZE__)
+} // __strnlen()
+
+// EOF strnlen.cxx
new file mode 100644
--- /dev/null
+++ b/packages/language/c/libc/string/current/tests/strnlen.c
@@ -0,0 +1,133 @@
+//=================================================================
+//
+//        strnlen.c
+//
+//        Testcase for C library strnlen()
+//
+//=================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     wry
+// Contributors:  
+// Date:          2010-05-10
+// Description:   Testing for C library strnlen() function
+//
+//
+//####DESCRIPTIONEND####
+
+// INCLUDES
+
+#include <pkgconf/isoinfra.h>
+#include <string.h>
+#include <stdarg.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/libc/string/stringsupp.hxx>
+
+
+// FUNCTIONS
+
+void test_guts(char *buf, size_t real_len, size_t arg, size_t expected, int *nfails, int *ncases)
+{
+#if 0
+    // printf takes too much memory on some boards.
+    //diag_printf("testcase: buf `%s', len %u, n %u, expect %u\n", buf, real_len, arg, expected);
+#endif
+    size_t rv = strnlen(buf, arg);
+    if (rv != expected) {
+        CYG_TEST_FAIL("incorrect answer from strnlen case");
+#if 0
+        diag_printf("incorrect answer %u from case %u:%u (expected %u)", rv, real_len, arg, expected);
+#endif
+        ++*nfails;
+    }
+    ++*ncases;
+}
+
+void test(size_t strsize, int * nfails, int * ncases)
+{
+    int j;
+    char testbuf[1024];
+
+    CYG_ASSERTC(strsize <= sizeof(testbuf));
+    // Insist on checking the aligned-path code.
+    CYG_ASSERTC(!(CYG_LIBC_STR_UNALIGNED(testbuf)));
+
+    memset(testbuf, 'A', strsize);
+    testbuf[strsize] = 0;
+
+    for (j=1; j<(1+4*sizeof(CYG_WORD)) && j<=strsize; j++) {
+        // condition `j<=strsize' prevents underflow.
+        test_guts(testbuf, strsize, strsize-j, strsize-j, nfails, ncases);
+    }
+    for (j=0; j<(1+4*sizeof(CYG_WORD)); j++) {
+        test_guts(testbuf, strsize, strsize+j, strsize, nfails, ncases);
+    }
+}
+
+
+#if CYGINT_ISO_MAIN_STARTUP
+int main( int argc, char *argv[] )
+#else
+void cyg_user_start(void)
+#endif
+{
+#ifndef CYGFUN_LIBC_STRING_GNU_STRNLEN
+    CYG_TEST_NA("strnlen / CYGFUN_LIBC_STRING_GNU_STRNLEN disabled");
+#else
+
+    CYG_TEST_INIT();
+    CYG_TEST_INFO("strnlen exhaustive testing");
+#if defined(CYGIMP_LIBC_STRING_PREFER_SMALL_TO_FAST)
+    CYG_TEST_INFO("strnlen: NOTE: CYGIMP_LIBC_STRING_PREFER_SMALL_TO_FAST is defined");
+#endif
+
+    int t, nfails=0, ncases=0;
+
+#define DO(x) do { test(x, &nfails, &ncases); } while(0)
+    for (t=0; t<40; t++) DO(t);
+
+#if 0
+    diag_printf("strnlen: %u/%u cases passed", (ncases-nfails), ncases);
+#endif
+    if (!nfails) CYG_TEST_PASS("strnlen");
+    CYG_TEST_FINISH("strnlen");
+
+#endif
+} // main()
+
+
+// EOF strlen.c
--- a/packages/services/cpuload/current/ChangeLog
+++ b/packages/services/cpuload/current/ChangeLog
@@ -1,3 +1,7 @@
+2010-03-29  Lars Povlsen  <lpovlsen@vitesse.com>
+
+	* src/cpuload.cxx: Update idle_thread_loops reference (volatile, array)
+
 2003-02-24  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* cdl/cpuload.cdl: Add doc link.
--- a/packages/services/cpuload/current/src/cpuload.cxx
+++ b/packages/services/cpuload/current/src/cpuload.cxx
@@ -58,6 +58,7 @@
 #include <cyg/kernel/kapi.h>
 #include <cyg/hal/hal_arch.h> 
 #include <cyg/cpuload/cpuload.h>
+#include <cyg/kernel/sched.hxx>
 
 /* Here we run the idle thread as a high priority thread for 0.1
    second.  We see how much the counter in the idle loop is
@@ -65,7 +66,7 @@
    running at priority 1 and 2 */
 
 static cyg_thread thread;
-externC cyg_uint32 idle_thread_loops;
+externC cyg_uint32 volatile idle_thread_loops[CYGNUM_KERNEL_CPU_MAX];
 char idle_stack[CYGNUM_HAL_STACK_SIZE_MINIMUM];
 
 extern void idle_thread_main( CYG_ADDRESS data );
@@ -108,7 +109,7 @@ cyg_cpuload_calibrate(cyg_uint32  *calib
   cyg_alarm_initialize(alarmH,cyg_current_time()+10,0);
   cyg_alarm_enable(alarmH);
   
-  idle_loops_start = idle_thread_loops;
+  idle_loops_start = idle_thread_loops[CYG_KERNEL_CPU_THIS()];
   
   /* Dont be decieved, remember this is a multithreaded system ! */
   old_priority = cyg_thread_get_priority(cyg_thread_self());
@@ -116,7 +117,7 @@ cyg_cpuload_calibrate(cyg_uint32  *calib
   cyg_thread_resume(idleH);
   cyg_thread_set_priority(cyg_thread_self(),old_priority);
   
-  *calibration = idle_thread_loops - idle_loops_start;
+  *calibration = idle_thread_loops[CYG_KERNEL_CPU_THIS()] - idle_loops_start;
   cyg_alarm_delete(alarmH);
   cyg_thread_kill(idleH);
   cyg_thread_delete(idleH);
@@ -125,7 +126,7 @@ cyg_cpuload_calibrate(cyg_uint32  *calib
 static void 
 cpuload_alarm_func(cyg_handle_t alarm,cyg_addrword_t data) { 
   cyg_cpuload_t * cpuload = (cyg_cpuload_t *)data;
-  cyg_uint32 idle_loops_now = idle_thread_loops;
+  cyg_uint32 idle_loops_now = idle_thread_loops[CYG_KERNEL_CPU_THIS()];
   cyg_uint32 idle_loops;
   cyg_uint32 load;
   
@@ -162,7 +163,7 @@ cyg_cpuload_create(cyg_cpuload_t *cpuloa
   cpuload->average_1s = 0;
   cpuload->average_10s = 0;
   cpuload->calibration = calibration;
-  cpuload->last_idle_loops = idle_thread_loops;
+  cpuload->last_idle_loops = idle_thread_loops[CYG_KERNEL_CPU_THIS()];
 
   cyg_clock_to_counter(cyg_real_time_clock(),&counter);
   cyg_alarm_create(counter,