Mercurial > ecos-v2_0-branch
changeset 24:306eee292492 ecos-sw-1999-07-16
Merge from eCos master repository on 1999-07-16-05:47:06-BST
line wrap: on
line diff
--- a/packages/devs/wallclock/current/ChangeLog +++ b/packages/devs/wallclock/current/ChangeLog @@ -1,3 +1,7 @@ +1999-07-14 Jesper Skov <jskov@cygnus.co.uk> + + * src/emulate.cxx: Include pkgconf/kernel.h. + 1999-04-20 Jonathan Larmour <jlarmour@cygnus.co.uk> * tests/wallclock.cxx (cyg_start): Output message to show the test
--- a/packages/devs/wallclock/current/src/emulate.cxx +++ b/packages/devs/wallclock/current/src/emulate.cxx @@ -40,6 +40,10 @@ #include <pkgconf/wallclock.h> // Wallclock device config +#ifdef CYGIMP_WALLCLOCK_EMULATE + +#include <pkgconf/kernel.h> // Kernel config + #include <cyg/infra/cyg_type.h> // Common type definitions and support #include <cyg/hal/hal_diag.h> // HAL diagnostic output @@ -51,7 +55,6 @@ #include <cyg/kernel/sched.inl> -#ifdef CYGIMP_WALLCLOCK_EMULATE /*---------------------------------------------------------------------------*/ // Local static variables
--- a/packages/devs/watchdog/current/ChangeLog +++ b/packages/devs/watchdog/current/ChangeLog @@ -1,3 +1,9 @@ +1999-07-14 Jesper Skov <jskov@cygnus.co.uk> + + * src/mn10300.cxx: + * src/emulate.cxx: + Include pkgconf/kernel.h. + 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk> * tests/watchdog.cxx: The 'keep alive' message was interfering
--- a/packages/devs/watchdog/current/src/emulate.cxx +++ b/packages/devs/watchdog/current/src/emulate.cxx @@ -45,6 +45,8 @@ #ifdef CYGIMP_WATCHDOG_EMULATE +#include <pkgconf/kernel.h> // Kernel config + #include <cyg/kernel/ktypes.h> // base kernel types #include <cyg/infra/cyg_trac.h> // tracing macros #include <cyg/infra/cyg_ass.h> // assertion macros
--- a/packages/devs/watchdog/current/src/mn10300.cxx +++ b/packages/devs/watchdog/current/src/mn10300.cxx @@ -45,6 +45,8 @@ #if defined(CYG_HAL_MN10300_MN103002) && !defined(CYGIMP_WATCHDOG_EMULATE) +#include <pkgconf/kernel.h> // Kernel config + #include <cyg/kernel/ktypes.h> // base kernel types #include <cyg/infra/cyg_trac.h> // tracing macros #include <cyg/infra/cyg_ass.h> // assertion macros
--- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,8 @@ +1999-07-14 Hugo Tyson <hmt@cygnus.co.uk> + + * src/vectors.S: Add some startup debug via a LED macro - which + has different content depending on platform, of course. + 1999-06-22 Gary Thomas <gthomas@cygnus.co.uk> * src/vectors.S: Fix names of 'report' functions (debug dumps
--- a/packages/hal/arm/arch/current/src/vectors.S +++ b/packages/hal/arm/arch/current/src/vectors.S @@ -78,6 +78,10 @@ .file "vectors.S" + +.macro LED x +.endm + //========================================================================== // Hardware exception vectors. @@ -124,6 +128,8 @@ reset_vector: beq start #endif + LED 7 + PLATFORM_SETUP1 // Early stage platform initialization // see <cyg/hal/hal_platform_setup.h> @@ -139,6 +145,9 @@ reset_vector: // Ugly hack to get into supervisor mode ldr r2,[r1,#0x40] str r2,[r0,#0x28] + + LED 6 + swi // switch to supervisor mode #endif @@ -146,7 +155,9 @@ reset_vector: // Real startup code. We jump here from the reset vector to set up the world. .globl start start: - + + LED 5 + #if defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) // If we get restarted, hang here to avoid corrupting memory @@ -186,6 +197,8 @@ 10: ldr r2,[r1,#0x30] str r2,[r0,#0x30] + LED 4 + #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_STUBS) // Relocate [copy] data from ROM to RAM ldr r3,.__rom_data_start @@ -236,9 +249,13 @@ 1: str r0,[r1],#4 2: + LED 3 + // Call platform specific hardware initialization bl hal_hardware_init + LED 2 + // Run through static constructors bl cyg_hal_invoke_constructors @@ -246,6 +263,8 @@ 2: bl initialize_stub #endif + LED 7 + // This starts up the eCos kernel bl cyg_start _start_hang: @@ -689,7 +708,11 @@ PTR(__interrupt_stack) // Interrupt vector tables. // These tables contain the isr, data and object pointers used to deliver // interrupts to user code. - + +// Despite appearances, their sizes are not #defines, but .equ symbols +// generated by magic without proper dependencies in arm.inc +// Recompiling will not DTRT without manual intervention. + .data init_flag:
--- a/packages/hal/mips/arch/current/ChangeLog +++ b/packages/hal/mips/arch/current/ChangeLog @@ -1,3 +1,20 @@ +1999-07-09 Jonathan Larmour <jlarmour@cygnus.co.uk> + + * include/mips.inc: + * include/arch.inc: + * src/vectors.S: + Rename "cache" register to "cachectrl" to prevent confusion with + the "cache" instruction. + For symmetry therefore also rename mipsreg_cache to mipsreg_cachectrl + + * include/arch.inc (hal_cache_init): + Invalidate caches at startup + + * include/hal_cache.h: + Allow cache invalidation when cache disabled + Add _HAL_ASM_SET_MIPS_ISA() to allow use of cache macros in code + compiled with a MIPS ISA below 3 + 1999-06-25 Nick Garnett <nickg@cygnus.co.uk> * include/arch.inc:
--- a/packages/hal/mips/arch/current/include/arch.inc +++ b/packages/hal/mips/arch/current/include/arch.inc @@ -111,8 +111,8 @@ #endif #define mipsreg_pc (mipsreg_vector+mips_regsize) #define mipsreg_sr (mipsreg_pc+mips_regsize) -#define mipsreg_cache (mipsreg_sr+mips_regsize) -#define mipsreg_cause (mipsreg_cache+mips_regsize) +#define mipsreg_cachectrl (mipsreg_sr+mips_regsize) +#define mipsreg_cause (mipsreg_cachectrl+mips_regsize) #define mipsreg_badvr (mipsreg_cause+mips_regsize) #define mipsreg_prid (mipsreg_badvr+mips_regsize) #define mipsreg_config (mipsreg_prid+mips_regsize) @@ -536,6 +536,33 @@ hal_intc_translation_table: nop nop nop + + .set mips3 # Set ISA to MIPS 3 to allow cache insns + + # Now ensure the caches are invalidated - may be applicable if the + # target has soft-reset + # D-cache: + la a0,0x80000000 + addi a1,a0,0x2000 +1: + cache 0x01,0(a0) + addi a0,a0,0x10 + sub v0,a1,a0 + bgez v0,1b + nop # delay slot + + # I-cache: + la a0,0x80000000 + addi a1,a0,0x4000 +1: + cache 0x00,0(a0) + addi a0,a0,0x20 + sub v0,a1,a0 + bgez v0,1b + nop # delay slot + + .set mips0 # reset ISA to default + .endm #endif
--- a/packages/hal/mips/arch/current/include/hal_cache.h +++ b/packages/hal/mips/arch/current/include/hal_cache.h @@ -52,6 +52,13 @@ #include <cyg/hal/var_cache.h> +// Use this macro to allow the assembler to accept "cache" instructions, +// which are MIPS ISA 3. This is useful if someone is compiling +// with -mips2, but the architecture is really MIPS ISA 3. + +#define _HAL_ASM_SET_MIPS_ISA( _isal_ ) asm volatile ( ".set mips" ## #_isal_ ) + + //============================================================================= // Default Implementation. This uses the standard MIPS CP0 registers and // cache instructions. Note that not all variants will have all of the @@ -113,11 +120,10 @@ register CYG_ADDRESS _baddr_ = 0x80000000; \ register CYG_ADDRESS _addr_ = 0x80000000; \ register CYG_WORD _size_ = HAL_DCACHE_SIZE; \ - register CYG_WORD _state_; \ - HAL_DCACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ - for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ - { asm volatile ("cache 0x01,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(3); \ + for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ + { asm volatile ("cache 0x01,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(0); \ } #endif @@ -141,9 +147,12 @@ CYG_MACRO_START register CYG_WORD _size_ = (_asize_); \ register CYG_WORD _state_; \ HAL_DCACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ + if( _state_ ) { \ + _HAL_ASM_SET_MIPS_ISA(3); \ for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ { asm volatile ("cache 0x1d,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(0); \ + } \ CYG_MACRO_END #endif @@ -172,16 +181,19 @@ CYG_MACRO_END // This uses the hit-writeback-invalidate cache operation. #ifndef HAL_DCACHE_FLUSH_DEFINED #define HAL_DCACHE_FLUSH( _base_ , _asize_ ) \ -{ \ +CYG_MACRO_START \ register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_); \ register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_); \ register CYG_WORD _size_ = (_asize_); \ register CYG_WORD _state_; \ HAL_DCACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ + if( _state_ ) { \ + _HAL_ASM_SET_MIPS_ISA(3); \ for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ { asm volatile ("cache 0x15,0(%0)" : : "r"(_addr_) ); } \ -} + _HAL_ASM_SET_MIPS_ISA(0); \ + } \ +CYG_MACRO_END #endif // Invalidate cache lines in the given range without writing to memory. @@ -192,11 +204,10 @@ CYG_MACRO_END register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_); \ register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_); \ register CYG_WORD _size_ = (_asize_); \ - register CYG_WORD _state_; \ - HAL_DCACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ - for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ - { asm volatile ("cache 0x11,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(3); \ + for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ + { asm volatile ("cache 0x11,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(0); \ } #endif @@ -204,16 +215,19 @@ CYG_MACRO_END // This uses the hit-writeback cache operation. #ifndef HAL_DCACHE_STORE_DEFINED #define HAL_DCACHE_STORE( _base_ , _asize_ ) \ -{ \ +CYG_MACRO_START \ register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_); \ register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_); \ register CYG_WORD _size_ = (_asize_); \ register CYG_WORD _state_; \ HAL_DCACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ + if( _state_ ) { \ + _HAL_ASM_SET_MIPS_ISA(3); \ for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ { asm volatile ("cache 0x19,0(%0)" : : "r"(_addr_) ); } \ -} + _HAL_ASM_SET_MIPS_ISA(0); \ + } \ +CYG_MACRO_END #endif // Preread the given range into the cache with the intention of reading @@ -248,15 +262,14 @@ CYG_MACRO_END // Invalidate the entire cache // This uses the index-invalidate cache operation. #ifndef HAL_ICACHE_INVALIDATE_ALL_DEFINED -#define HAL_ICACHE_INVALIDATE_ALL() \ -{ \ - register CYG_ADDRESS _baddr_ = 0x80000000; \ - register CYG_ADDRESS _addr_ = 0x80000000; \ - register CYG_WORD _state_; \ - HAL_ICACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ - for( ; _addr_ < _baddr_+HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \ - { asm volatile ("cache 0x00,0(%0)" : : "r"(_addr_) ); } \ +#define HAL_ICACHE_INVALIDATE_ALL() \ +{ \ + register CYG_ADDRESS _baddr_ = 0x80000000; \ + register CYG_ADDRESS _addr_ = 0x80000000; \ + _HAL_ASM_SET_MIPS_ISA(3); \ + for( ; _addr_ < _baddr_+HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \ + { asm volatile ("cache 0x00,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(0); \ } #endif @@ -280,9 +293,12 @@ CYG_MACRO_START register CYG_WORD _size_ = (_asize_); \ register CYG_WORD _state_; \ HAL_ICACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ + if( _state_ ) { \ + _HAL_ASM_SET_MIPS_ISA(3); \ for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ { asm volatile ("cache 0x1c,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(0); \ + } \ CYG_MACRO_END #endif @@ -307,11 +323,10 @@ CYG_MACRO_END register CYG_ADDRESS _baddr_ = (CYG_ADDRESS)(_base_); \ register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_); \ register CYG_WORD _size_ = (_asize_); \ - register CYG_WORD _state_; \ - HAL_ICACHE_IS_ENABLED( _state_ ); \ - if( _state_ ) \ - for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_ICACHE_LINE_SIZE ) \ - { asm volatile ("cache 0x10,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(3); \ + for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_ICACHE_LINE_SIZE ) \ + { asm volatile ("cache 0x10,0(%0)" : : "r"(_addr_) ); } \ + _HAL_ASM_SET_MIPS_ISA(0); \ } #endif
--- a/packages/hal/mips/arch/current/include/mips.inc +++ b/packages/hal/mips/arch/current/include/mips.inc @@ -127,7 +127,7 @@ #define context $4 // TLB context register #define pagemask $5 // TLB page size mask #define wired $6 // TLB wired boundary -#define cache $7 // Cache control +#define cachectrl $7 // Cache control #define badvr $8 // Bad virtual address #define count $9 // Timer cycle count register #define tlbhi $10 // TLB virtual address match register
--- a/packages/hal/mips/arch/current/src/vectors.S +++ b/packages/hal/mips/arch/current/src/vectors.S @@ -344,7 +344,7 @@ FUNC_START(__default_exception_vsr) # save remaining machine state registers mfc0 t0,cause mfc0 t1,status - mfc0 t2,cache + mfc0 t2,cachectrl mfc0 t3,badvr mfc0 t4,config mfc0 t5,prid @@ -352,7 +352,7 @@ FUNC_START(__default_exception_vsr) sw t0,mipsreg_cause(sp) sw t1,mipsreg_sr(sp) - sw t2,mipsreg_cache(sp) + sw t2,mipsreg_cachectrl(sp) sw t3,mipsreg_badvr(sp) sw t4,mipsreg_config(sp) sw t5,mipsreg_prid(sp) @@ -451,11 +451,11 @@ FUNC_START(__default_interrupt_vsr) sw k1,(mipsreg_regs+29*4)(sp) # store in reg dump mfc0 t1,status - mfc0 t2,cache + mfc0 t2,cachectrl mfc0 t3,epc sw t1,mipsreg_sr(sp) - sw t2,mipsreg_cache(sp) + sw t2,mipsreg_cachectrl(sp) sw t3,mipsreg_pc(sp) hal_fpu_save sp @@ -605,11 +605,11 @@ restore_state: hal_fpu_load sp - lw t0,mipsreg_cache(sp) + lw t0,mipsreg_cachectrl(sp) lw t1,mipsreg_hi(sp) lw t2,mipsreg_lo(sp) - mtc0 t0,cache + mtc0 t0,cachectrl mthi t1 mtlo t2
--- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,22 @@ +1999-07-14 Hugo Tyson <hmt@cygnus.co.uk> + + * tests/kcache1.c (entry0): Also perform timing tests with + HAL_DCACHE_INVALIDATE_ALL and/or HAL_ICACHE_INVALIDATE_ALL in the + loop if provided by the HAL. Invalidating the Data cache can + spoil clock operation, so elapsed time appears to be 0. + + * tests/kcache2.c (entry0): Replace the "if (0)" for having a + copy-back cache with a proper test on a HAL macro. Even though I + couldn't actually get those parts of the test to work on the + platform I'm currently working on. + +1999-07-09 Jesper Skov <jskov@cygnus.co.uk> + PR 20210, 20142 + * tests/stress_threads.c: Shifted thread priorities to make room + for main() at priority 0. + + Fixed indentation. + 1999-07-08 Jesper Skov <jskov@cygnus.co.uk> PR 20244 * tests/stress_threads.c: Changed cyg_user_start() to main()
--- a/packages/kernel/current/tests/PKGconf.mak +++ b/packages/kernel/current/tests/PKGconf.mak @@ -45,6 +45,7 @@ ifndef CYG_HAL_ARM TESTS += kcache1 kcache2 endif + ifndef CYGPKG_HAL_ARM_AEB TESTS += stress_threads endif
--- a/packages/kernel/current/tests/kcache1.c +++ b/packages/kernel/current/tests/kcache1.c @@ -128,6 +128,86 @@ void time1(void) } // ------------------------------------------------------------------------- +// With an ICache invalidate in the middle: +#ifdef HAL_ICACHE_INVALIDATE_ALL +static void time0II(register cyg_uint32 stride) +{ + register cyg_uint32 j,k; + cyg_tick_count_t count0, count1; + cyg_ucount32 t; + register char c; + + count0 = cyg_current_time(); + + k = 0; + if ( cyg_test_is_simulator ) + k = 3960; + + for(; k<4000;k++) { + for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) { + HAL_ICACHE_INVALIDATE_ALL(); + c=m[stride*j]; + } + } + + count1 = cyg_current_time(); + t = count1 - count0; + diag_printf("stride=%d, time=%d\n", stride, t); +} + +// ------------------------------------------------------------------------- + +void time1II(void) +{ + cyg_uint32 i; + + for(i=1; i<=MAX_STRIDE; i+=i) { + time0II(i); + } +} +#endif +// ------------------------------------------------------------------------- +// With a DCache invalidate in the middle: +#ifdef HAL_DCACHE_INVALIDATE_ALL +static void time0DI(register cyg_uint32 stride) +{ + register cyg_uint32 j,k; + cyg_tick_count_t count0, count1; + cyg_ucount32 t; + register char c; + + count0 = cyg_current_time(); + + HAL_DCACHE_SYNC(); + + k = 0; + if ( cyg_test_is_simulator ) + k = 3960; + + for(; k<4000;k++) { + for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) { + HAL_DCACHE_INVALIDATE_ALL(); + c=m[stride*j]; + } + } + + count1 = cyg_current_time(); + t = count1 - count0; + diag_printf("stride=%d, time=%d\n", stride, t); +} + +// ------------------------------------------------------------------------- + +void time1DI(void) +{ + cyg_uint32 i; + + for(i=1; i<=MAX_STRIDE; i+=i) { + time0DI(i); + } +} +#endif +// ------------------------------------------------------------------------- // This test could be improved by counting number of passes possible // in a given number of ticks. @@ -203,9 +283,44 @@ static void entry0( cyg_addrword_t data HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); - CYG_TEST_INFO("Dcache off Icache off"); + CYG_TEST_INFO("Dcache off Icache off (again)"); + time1(); + +#if defined(HAL_DCACHE_INVALIDATE_ALL) || defined(HAL_ICACHE_INVALIDATE_ALL) + HAL_DISABLE_INTERRUPTS(oldints); + HAL_DCACHE_PURGE_ALL(); + HAL_ICACHE_INVALIDATE_ALL(); + HAL_DCACHE_INVALIDATE_ALL(); + HAL_ICACHE_ENABLE(); + HAL_DCACHE_ENABLE(); + HAL_RESTORE_INTERRUPTS(oldints); + CYG_TEST_INFO("Dcache on Icache on (again)"); time1(); +#ifdef HAL_ICACHE_INVALIDATE_ALL + HAL_DISABLE_INTERRUPTS(oldints); + HAL_DCACHE_PURGE_ALL(); + HAL_ICACHE_INVALIDATE_ALL(); + HAL_DCACHE_INVALIDATE_ALL(); + HAL_ICACHE_ENABLE(); + HAL_DCACHE_ENABLE(); + HAL_RESTORE_INTERRUPTS(oldints); + CYG_TEST_INFO("Dcache on Icache on: invalidate ICache each time"); + time1II(); +#endif +#ifdef HAL_DCACHE_INVALIDATE_ALL + HAL_DISABLE_INTERRUPTS(oldints); + HAL_DCACHE_PURGE_ALL(); + HAL_ICACHE_INVALIDATE_ALL(); + HAL_DCACHE_INVALIDATE_ALL(); + HAL_ICACHE_ENABLE(); + HAL_DCACHE_ENABLE(); + HAL_RESTORE_INTERRUPTS(oldints); + CYG_TEST_INFO("Dcache on Icache on: invalidate DCache (expect bogus times)"); + time1DI(); +#endif +#endif // either INVALIDATE_ALL macro + #endif // HAL_CACHE_UNIFIED CYG_TEST_PASS_FINISH("End of test");
--- a/packages/kernel/current/tests/kcache2.c +++ b/packages/kernel/current/tests/kcache2.c @@ -539,6 +539,9 @@ static void time_dlock(void) // ------------------------------------------------------------------------- static void entry0( cyg_addrword_t data ) { +#ifdef HAL_DCACHE_QUERY_WRITE_MODE + int wmode; +#endif #ifdef HAL_DCACHE_LOCK time_dlock(); #endif @@ -559,7 +562,10 @@ static void entry0( cyg_addrword_t data #endif // The below tests only work on a copy-back cache. - if (0) { +#ifdef HAL_DCACHE_QUERY_WRITE_MODE + HAL_DCACHE_QUERY_WRITE_MODE( wmode ); + + if ( HAL_DCACHE_WRITEBACK_MODE == wmode ) { #ifdef HAL_DCACHE_FLUSH test_dflush(); #endif @@ -567,6 +573,7 @@ static void entry0( cyg_addrword_t data test_dinvalidate(); #endif } +#endif // def HAL_DCACHE_QUERY_WRITE_MODE CYG_TEST_PASS_FINISH("End of test"); }
--- a/packages/kernel/current/tests/stress_threads.c +++ b/packages/kernel/current/tests/stress_threads.c @@ -84,19 +84,29 @@ #define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) -/* Allocate priorities in this order. This ensures that handlers - (which are the ones using the CPU) get enough CPU time to actually - complete their tasks. */ +// The number of instances in each thread class #define N_MAIN 1 #define MAX_HANDLERS 19 #define N_LISTENERS 4 #define N_CLIENTS 4 +#define N_THREADS (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS) -#if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS)) +/* Allocate priorities in this order. This ensures that handlers + (which are the ones using the CPU) get enough CPU time to actually + complete their tasks. */ +//#define P_MAIN 0 // This is defined by libc +#define P_MAIN_PROGRAM 1 +#define P_BASE_HANDLER 2 +#define P_BASE_LISTENER (P_BASE_HANDLER+MAX_HANDLERS) +#define P_BASE_CLIENT (P_BASE_LISTENER+N_LISTENERS) +#define P_MAX (P_BASE_CLIENT+N_CLIENTS) + + +#if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (P_MAX)) /* if we use the bitmap scheduler we must make sure we don't use the same priority more than once, so we must store those already in use */ -static volatile char priority_in_use[N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS]; +static volatile char priority_in_use[P_MAX]; /* now declare (and allocate space for) some kernel objects, like the threads we will use */ @@ -117,6 +127,9 @@ cyg_handle_t handlerH[MAX_HANDLERS]; cyg_handle_t listenerH[N_LISTENERS]; cyg_handle_t clientH[N_CLIENTS]; +/* space for thread names */ +char thread_name[P_MAX][20]; + /* and now variables for the procedure which is the thread */ cyg_thread_entry_t main_program, client_program, listener_program, handler_program; @@ -137,7 +150,7 @@ int client_makes_request = 0; /* indicates that it's time to print out a report */ int time_to_report = 0; - /* print status after a delay of this many secs. */ +/* print status after a delay of this many secs. */ int time_report_delay; /*** now application-specific variables ***/ @@ -170,7 +183,7 @@ void sc_thread_create( cyg_ucount32 stack_size, /* stack size, 0 = default */ cyg_handle_t *handle, /* returned thread handle */ cyg_thread *thread /* put thread here */ -); + ); int get_handler_slot(cyg_handle_t current_threadH); void perform_stressful_tasks(void); @@ -191,83 +204,81 @@ cyg_alarm report_alarm; int main(void) { - int i; + int i; - CYG_TEST_INIT(); - CYG_TEST_INFO("# Entering stress's cyg_user_start() function"); + CYG_TEST_INIT(); + CYG_TEST_INFO("# Entering stress's cyg_user_start() function"); - cyg_mutex_init(&client_request_lock); - cyg_mutex_init(&statistics_print_lock); - cyg_mutex_init(&free_handler_lock); + cyg_mutex_init(&client_request_lock); + cyg_mutex_init(&statistics_print_lock); + cyg_mutex_init(&free_handler_lock); - /* initialize statistics */ - memset(&statistics, 0, sizeof(statistics)); + /* initialize statistics */ + memset(&statistics, 0, sizeof(statistics)); - /* clear priority table */ - for (i = 0; i < sizeof(priority_in_use); i++) - priority_in_use[i] = 0; + /* clear priority table */ + for (i = 0; i < sizeof(priority_in_use); i++) + priority_in_use[i] = 0; - /* initialize main thread */ - { - char thread_name[] = "main"; - - sc_thread_create(0, main_program, (cyg_addrword_t) 0, - thread_name, (void *) main_stack, STACK_SIZE, - &mainH, &main_thread_s); - priority_in_use[0]++; - } + /* initialize main thread */ + { + sc_thread_create(P_MAIN_PROGRAM, main_program, (cyg_addrword_t) 0, + "main_program", (void *) main_stack, STACK_SIZE, + &mainH, &main_thread_s); + priority_in_use[P_MAIN_PROGRAM]++; + } - /* initialize all handler threads to not be in use */ - for (i = 0; i < MAX_HANDLERS; ++i) { - handler_thread_in_use[i] = 0; - } - for (i = 0; i < N_LISTENERS; ++i) { - int prio; - char thread_name[20]; - sprintf(thread_name, "listener-%02d", i); - prio = N_MAIN + MAX_HANDLERS + i; - sc_thread_create(prio, listener_program, (cyg_addrword_t) i, - thread_name, (void *) listener_stack[i], STACK_SIZE, - &listenerH[i], &listener_thread_s[i]); - CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); - priority_in_use[prio]++; - } - for (i = 0; i < N_CLIENTS; ++i) { - int prio; - char thread_name[20]; - sprintf(thread_name, "client-%02d", i); - prio = N_MAIN + MAX_HANDLERS + N_LISTENERS + i; - sc_thread_create(prio, client_program, (cyg_addrword_t) i, - thread_name, (void *) client_stack[i], STACK_SIZE, - &(clientH[i]), &client_thread_s[i]); - CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); - priority_in_use[prio]++; - } + /* initialize all handler threads to not be in use */ + for (i = 0; i < MAX_HANDLERS; ++i) { + handler_thread_in_use[i] = 0; + } + for (i = 0; i < N_LISTENERS; ++i) { + int prio = P_BASE_LISTENER + i; + char* name = &thread_name[prio][0]; + sprintf(name, "listener-%02d/%02d", i, prio); + sc_thread_create(prio, listener_program, (cyg_addrword_t) i, + name, (void *) listener_stack[i], STACK_SIZE, + &listenerH[i], &listener_thread_s[i]); + CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); + priority_in_use[prio]++; + } + for (i = 0; i < N_CLIENTS; ++i) { + int prio = P_BASE_CLIENT + i; + char* name = &thread_name[prio][0]; + sprintf(name, "client-%02d/%02d", i, prio); + sc_thread_create(prio, client_program, (cyg_addrword_t) i, + name, (void *) client_stack[i], STACK_SIZE, + &(clientH[i]), &client_thread_s[i]); + CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); + priority_in_use[prio]++; + } - cyg_thread_resume(mainH); - for (i = 0; i < N_CLIENTS; ++i) { - cyg_thread_resume(clientH[i]); - } - for (i = 0; i < N_LISTENERS; ++i) { - cyg_thread_resume(listenerH[i]); - } + cyg_thread_resume(mainH); + for (i = 0; i < N_CLIENTS; ++i) { + cyg_thread_resume(clientH[i]); + } + for (i = 0; i < N_LISTENERS; ++i) { + cyg_thread_resume(listenerH[i]); + } + + /* set up the alarm which gives periodic wakeups to say "time to + print a report */ + system_clockH = cyg_real_time_clock(); + cyg_clock_to_counter(system_clockH, &counterH); - /* set up the alarm which gives periodic wakeups to say "time to - print a report */ - system_clockH = cyg_real_time_clock(); - cyg_clock_to_counter(system_clockH, &counterH); + cyg_alarm_create(counterH, report_alarm_func, + (cyg_addrword_t) 4000, + &report_alarmH, &report_alarm); + if (cyg_test_is_simulator) { + time_report_delay = 2; + } else { + time_report_delay = 30; + } - cyg_alarm_create(counterH, report_alarm_func, - (cyg_addrword_t) 4000, - &report_alarmH, &report_alarm); - if (cyg_test_is_simulator) { - time_report_delay = 2; - } else { - time_report_delay = 30; - } + cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, + time_report_delay*100); - cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, - time_report_delay*100); + return 0; } /* main_program() -- frees resources and prints status. */ @@ -340,25 +351,25 @@ void main_program(cyg_addrword_t data) /* client_program() -- an obnoxious client which makes a lot of requests */ void client_program(cyg_addrword_t data) { - int delay; + int delay; - printf("# Starting client-%d\n", (int) data); + printf("# Starting client-%d\n", (int) data); - system_clockH = cyg_real_time_clock(); - cyg_clock_to_counter(system_clockH, &counterH); + system_clockH = cyg_real_time_clock(); + cyg_clock_to_counter(system_clockH, &counterH); - for (;;) { - delay = (rand() % 20); + for (;;) { + delay = (rand() % 20); - /* now send a request to the server */ - cyg_mutex_lock(&client_request_lock); { - ++client_makes_request; + /* now send a request to the server */ + cyg_mutex_lock(&client_request_lock); { + ++client_makes_request; /* printf("client_makes_request %d\n", client_makes_request); */ - } cyg_mutex_unlock(&client_request_lock); + } cyg_mutex_unlock(&client_request_lock); - cyg_thread_delay(10+delay); + cyg_thread_delay(10+delay); /* cyg_thread_delay(0); */ - } + } } /* listener_program() -- listens for a request and spawns a handler to @@ -381,17 +392,21 @@ void listener_program(cyg_addrword_t dat if (make_request) { int prio; + char* name; /* printf("just got a request from a client (count = %d)\n", */ /* client_makes_request); */ handler_slot = get_handler_slot(listenerH[(int) data]); - prio = N_MAIN+handler_slot; + prio = P_BASE_HANDLER+handler_slot; + + name = &thread_name[prio][0]; + sprintf(name, "handler-%02d/%02d", handler_slot, prio); CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); priority_in_use[prio]++; sc_thread_create(prio, handler_program, (cyg_addrword_t) handler_slot, - "handler", (void *) handler_stack[handler_slot], + name, (void *) handler_stack[handler_slot], STACK_SIZE2, &handlerH[handler_slot], &handler_thread_s[handler_slot]); cyg_thread_resume(handlerH[handler_slot]); @@ -405,32 +420,32 @@ void listener_program(cyg_addrword_t dat /* handler_program() -- is spawned to handle each incoming request */ void handler_program(cyg_addrword_t data) { - /* here is where we perform specific stressful tasks */ - perform_stressful_tasks(); + /* here is where we perform specific stressful tasks */ + perform_stressful_tasks(); - cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000))))); + cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000))))); /* cyg_thread_delay(0); */ - ++statistics.thread_exits; - { - // Loop until the handler id and priority can be communicated to - // the main_program. - int freed = 0; - do { - cyg_mutex_lock(&free_handler_lock); { - if (-1 == free_handler_id) { - free_handler_id = data; - free_handler_pri = N_MAIN+(int) data; - freed = 1; - } - } cyg_mutex_unlock(&free_handler_lock); - if (!freed) - cyg_thread_delay(2); - } while (!freed); - } + ++statistics.thread_exits; + { + // Loop until the handler id and priority can be communicated to + // the main_program. + int freed = 0; + do { + cyg_mutex_lock(&free_handler_lock); { + if (-1 == free_handler_id) { + free_handler_id = data; + free_handler_pri = P_BASE_HANDLER+(int) data; + freed = 1; + } + } cyg_mutex_unlock(&free_handler_lock); + if (!freed) + cyg_thread_delay(2); + } while (!freed); + } - // Then exit. - cyg_thread_exit(); + // Then exit. + cyg_thread_exit(); } /* look for an available handler thread */ @@ -463,65 +478,65 @@ void perform_stressful_tasks() { #define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */ #define MALLOCED_BASE_SIZE 1 /* basic size in bytes */ - char *spaces[MAX_MALLOCED_SPACES]; - unsigned int i; + char *spaces[MAX_MALLOCED_SPACES]; + unsigned int i; - cyg_mutex_t tmp_lock; + cyg_mutex_t tmp_lock; - cyg_uint8 pool_space[10][100]; - cyg_handle_t mempool_handles[10]; - cyg_mempool_fix mempool_objects[10]; + cyg_uint8 pool_space[10][100]; + cyg_handle_t mempool_handles[10]; + cyg_mempool_fix mempool_objects[10]; - cyg_mutex_init(&tmp_lock); + cyg_mutex_init(&tmp_lock); - /* here I use malloc, which uses the kernel's variable memory pools. - note that malloc/free is a bit simple-minded here: it does not - try to really fragment things, and it does not try to make the - allocation/deallocation concurrent with other thread execution - (although I'm about to throw in a yield()) */ - for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { - ++statistics.malloc_tries; + /* here I use malloc, which uses the kernel's variable memory pools. + note that malloc/free is a bit simple-minded here: it does not + try to really fragment things, and it does not try to make the + allocation/deallocation concurrent with other thread execution + (although I'm about to throw in a yield()) */ + for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { + ++statistics.malloc_tries; /* spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */ - spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE); - if (i % (MAX_MALLOCED_SPACES/10) == 0) { - cyg_thread_yield(); + spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE); + if (i % (MAX_MALLOCED_SPACES/10) == 0) { + cyg_thread_yield(); + } + if (i % (MAX_MALLOCED_SPACES/15) == 0) { + cyg_thread_delay(i % 5); + } } - if (i % (MAX_MALLOCED_SPACES/15) == 0) { - cyg_thread_delay(i % 5); - } - } - /* now free it all up */ - for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { - if (spaces[i] != NULL) { - unsigned int j; - for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) { - spaces[i][j] = 0xAA; /* write a bit pattern */ - } - free(spaces[i]); - } else { - ++statistics.malloc_failures; + /* now free it all up */ + for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { + if (spaces[i] != NULL) { + unsigned int j; + for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) { + spaces[i][j] = 0xAA; /* write a bit pattern */ + } + free(spaces[i]); + } else { + ++statistics.malloc_failures; + } } - } - /* now allocate and then free some fixed-size memory pools; for - now this is simple-minded because it does not have many threads - sharing the memory pools and racing for memory. */ - for (i = 0; i < 10; ++i) { - cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3, - &mempool_handles[i], &mempool_objects[i]); - } + /* now allocate and then free some fixed-size memory pools; for + now this is simple-minded because it does not have many threads + sharing the memory pools and racing for memory. */ + for (i = 0; i < 10; ++i) { + cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3, + &mempool_handles[i], &mempool_objects[i]); + } - for (i = 0; i < 10; ++i) { - spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]); - } + for (i = 0; i < 10; ++i) { + spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]); + } - for (i = 0; i < 10; ++i) { - if (spaces[i]) { - cyg_mempool_fix_delete(mempool_handles[i]); + for (i = 0; i < 10; ++i) { + if (spaces[i]) { + cyg_mempool_fix_delete(mempool_handles[i]); + } } - } - cyg_mutex_destroy(&tmp_lock); + cyg_mutex_destroy(&tmp_lock); } /* report_alarm_func() is invoked as an alarm handler, so it should be @@ -538,31 +553,31 @@ void report_alarm_func(cyg_handle_t alar void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, cyg_alarm *death_alarm_p, int *killed_p) { - cyg_handle_t system_clockH, counterH; - cyg_resolution_t rtc_res; + cyg_handle_t system_clockH, counterH; + cyg_resolution_t rtc_res; - system_clockH = cyg_real_time_clock(); - cyg_clock_to_counter(system_clockH, &counterH); + system_clockH = cyg_real_time_clock(); + cyg_clock_to_counter(system_clockH, &counterH); - cyg_alarm_create(counterH, death_alarm_func, - (cyg_addrword_t) killed_p, - deathHp, death_alarm_p); - rtc_res = cyg_clock_get_resolution(system_clockH); - { - cyg_tick_count_t tick_delay; - tick_delay = (long long) - ((1000000000.0*rtc_res.divisor) - *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend)); - if ( cyg_test_is_simulator ) - tick_delay /= 10; + cyg_alarm_create(counterH, death_alarm_func, + (cyg_addrword_t) killed_p, + deathHp, death_alarm_p); + rtc_res = cyg_clock_get_resolution(system_clockH); + { + cyg_tick_count_t tick_delay; + tick_delay = (long long) + ((1000000000.0*rtc_res.divisor) + *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend)); + if ( cyg_test_is_simulator ) + tick_delay /= 10; #ifdef CYGPKG_HAL_I386_LINUX - // 20 seconds is a long time compared to the run time of other tests. - // Reduce to 10 seconds, allowing more tests to get run. - tick_delay /= 2; + // 20 seconds is a long time compared to the run time of other tests. + // Reduce to 10 seconds, allowing more tests to get run. + tick_delay /= 2; #endif - cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0); - } + cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0); + } } #endif @@ -571,9 +586,9 @@ void setup_death_alarm(cyg_addrword_t da thread is constantly checking. */ void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) { - int *killed_p; - killed_p = (int *) data; - *killed_p = 1; + int *killed_p; + killed_p = (int *) data; + *killed_p = 1; } /* now I write the sc_ versions of the cyg_functions */ @@ -586,51 +601,54 @@ void sc_thread_create( cyg_ucount32 stack_size, /* stack size, 0 = default */ cyg_handle_t *handle, /* returned thread handle */ cyg_thread *thread /* put thread here */ -) + ) { /*printf("Creating a thread -- priority is %lu\n", (unsigned long) sched_info);*/ /* fflush(stdout); */ - ++statistics.thread_creations; - cyg_thread_create(sched_info, entry, entry_data, name, - stack_base, stack_size, handle, thread); + ++statistics.thread_creations; + cyg_thread_create(sched_info, entry, entry_data, name, + stack_base, stack_size, handle, thread); + + CYG_ASSERT(cyg_thread_get_priority(*handle) == (cyg_priority_t) sched_info, + "Didn't get requested priority!"); } void print_statistics(int print_full) { - int i; - static int print_count = 0; + int i; + static int print_count = 0; - printf("State dump %d (time %02d.%02d.%02d)\n", - print_count, - print_count*time_report_delay / (60*60), // hours - (print_count*time_report_delay / 60) % 60, // minutes - (print_count*time_report_delay ) % 60); // seconds - print_count++; + printf("State dump %d (time %02d.%02d.%02d)\n", + print_count, + print_count*time_report_delay / (60*60), // hours + (print_count*time_report_delay / 60) % 60, // minutes + (print_count*time_report_delay ) % 60); // seconds + print_count++; - cyg_mutex_lock(&statistics_print_lock); { - printf(" Handler-invocations: "); - for (i = 0; i < MAX_HANDLERS; ++i) { - printf("%4lu ", statistics.handler_invocation_histogram[i]); + cyg_mutex_lock(&statistics_print_lock); { + printf(" Handler-invocations: "); + for (i = 0; i < MAX_HANDLERS; ++i) { + printf("%4lu ", statistics.handler_invocation_histogram[i]); + } + printf("\n"); + printf(" malloc()-tries/failures: -- %7lu %7lu\n", + statistics.malloc_tries, statistics.malloc_failures); + printf(" client_makes_request: %d\n", client_makes_request); + } cyg_mutex_unlock(&statistics_print_lock); + + // Add: Also occasionally dump individual threads' stack status. + if (0 == print_count % 5 || print_full) { + cyg_test_dump_interrupt_stack_stats( " Status" ); + cyg_test_dump_idlethread_stack_stats( " Status" ); } - printf("\n"); - printf(" malloc()-tries/failures: -- %7lu %7lu\n", - statistics.malloc_tries, statistics.malloc_failures); - printf(" client_makes_request: %d\n", client_makes_request); - } cyg_mutex_unlock(&statistics_print_lock); - - // Add: Also occasionally dump individual threads' stack status. - if (0 == print_count % 5 || print_full) { - cyg_test_dump_interrupt_stack_stats( " Status" ); - cyg_test_dump_idlethread_stack_stats( " Status" ); - } } #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ - /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ +/* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ #define N_A_MSG "not enough priorities available" #endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ - /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ +/* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ #else /* CYGSEM_LIBC_MALLOC */ # define N_A_MSG "this test needs malloc"
