From 88d594a3d52cb5938521619bca0def8e5b040cf0 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 24 May 1995 21:39:42 +0000 Subject: Fully tested on all in-house targets --- cpukit/score/cpu/hppa1.1/cpu.c | 2 +- cpukit/score/cpu/i386/asm.h | 2 +- cpukit/score/cpu/i386/rtems/asm.h | 2 +- cpukit/score/cpu/i960/asm.h | 2 +- cpukit/score/cpu/m68k/asm.h | 2 +- cpukit/score/cpu/m68k/rtems/asm.h | 2 +- cpukit/score/cpu/no_cpu/asm.h | 2 +- cpukit/score/cpu/no_cpu/rtems/asm.h | 2 +- cpukit/score/cpu/unix/cpu.c | 25 ++++++---- cpukit/score/include/rtems/score/watchdog.h | 61 ++---------------------- cpukit/score/inline/rtems/score/watchdog.inl | 35 -------------- cpukit/score/macros/rtems/score/watchdog.inl | 27 ----------- cpukit/score/src/heap.c | 40 +++++++++------- cpukit/score/src/watchdog.c | 71 ++++++++++++++++++++-------- 14 files changed, 104 insertions(+), 171 deletions(-) (limited to 'cpukit/score') diff --git a/cpukit/score/cpu/hppa1.1/cpu.c b/cpukit/score/cpu/hppa1.1/cpu.c index b69a172b4e..027ed07333 100644 --- a/cpukit/score/cpu/hppa1.1/cpu.c +++ b/cpukit/score/cpu/hppa1.1/cpu.c @@ -14,7 +14,7 @@ * Division Incorporated makes no representations about the * suitability of this software for any purpose. * - * $Id$ + * cpu.c,v 1.2 1995/05/09 20:11:35 joel Exp */ #include diff --git a/cpukit/score/cpu/i386/asm.h b/cpukit/score/cpu/i386/asm.h index f123defcd9..16cf6c3235 100644 --- a/cpukit/score/cpu/i386/asm.h +++ b/cpukit/score/cpu/i386/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/i386/rtems/asm.h b/cpukit/score/cpu/i386/rtems/asm.h index f123defcd9..16cf6c3235 100644 --- a/cpukit/score/cpu/i386/rtems/asm.h +++ b/cpukit/score/cpu/i386/rtems/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/i960/asm.h b/cpukit/score/cpu/i960/asm.h index 1c40601473..e8fc986402 100644 --- a/cpukit/score/cpu/i960/asm.h +++ b/cpukit/score/cpu/i960/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/m68k/asm.h b/cpukit/score/cpu/m68k/asm.h index 068c58058c..58bb04bdf9 100644 --- a/cpukit/score/cpu/m68k/asm.h +++ b/cpukit/score/cpu/m68k/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/m68k/rtems/asm.h b/cpukit/score/cpu/m68k/rtems/asm.h index 068c58058c..58bb04bdf9 100644 --- a/cpukit/score/cpu/m68k/rtems/asm.h +++ b/cpukit/score/cpu/m68k/rtems/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/no_cpu/asm.h b/cpukit/score/cpu/no_cpu/asm.h index 69b1f0f825..97464d5b3a 100644 --- a/cpukit/score/cpu/no_cpu/asm.h +++ b/cpukit/score/cpu/no_cpu/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/no_cpu/rtems/asm.h b/cpukit/score/cpu/no_cpu/rtems/asm.h index 69b1f0f825..97464d5b3a 100644 --- a/cpukit/score/cpu/no_cpu/rtems/asm.h +++ b/cpukit/score/cpu/no_cpu/rtems/asm.h @@ -31,7 +31,7 @@ */ #define ASM -#include +#include /* * Recent versions of GNU cpp define variables which indicate the diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c index ed94953d58..68397a4e29 100644 --- a/cpukit/score/cpu/unix/cpu.c +++ b/cpukit/score/cpu/unix/cpu.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -225,18 +224,28 @@ void _CPU_Context_Initialize( unsigned32 *_stack_base, unsigned32 _size, unsigned32 _new_level, - proc_ptr *_entry_point + void *_entry_point ) { unsigned32 *addr; unsigned32 jmp_addr; - unsigned32 _stack; + unsigned32 _stack_low; /* lowest "stack aligned" address */ + unsigned32 _stack_high; /* highest "stack aligned" address */ unsigned32 _the_size; jmp_addr = (unsigned32) _entry_point; - _stack = ((unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT); - _stack &= ~(CPU_STACK_ALIGNMENT - 1); + /* + * On CPUs with stacks which grow down, we build the stack + * based on the _stack_high address. On CPUs with stacks which + * grow up, we build the stack based on the _stack_low address. + */ + + _stack_low = ((unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT); + _stack_low &= ~(CPU_STACK_ALIGNMENT - 1); + + _stack_high = ((unsigned32)(_stack_base) + _size); + _stack_high &= ~(CPU_STACK_ALIGNMENT - 1); _the_size = _size & ~(CPU_STACK_ALIGNMENT - 1); @@ -250,7 +259,7 @@ void _CPU_Context_Initialize( #if defined(hppa1_1) *(addr + RP_OFF) = jmp_addr; - *(addr + SP_OFF) = (unsigned32)(_stack + CPU_FRAME_SIZE); + *(addr + SP_OFF) = (unsigned32)(_stack_low + CPU_FRAME_SIZE); /* * See if we are using shared libraries by checking @@ -274,8 +283,8 @@ void _CPU_Context_Initialize( asm ("ta 0x03"); /* flush registers */ *(addr + RP_OFF) = jmp_addr + ADDR_ADJ_OFFSET; - *(addr + SP_OFF) = (unsigned32)(_stack +_the_size - CPU_FRAME_SIZE); - *(addr + FP_OFF) = (unsigned32)(_stack +_the_size); + *(addr + SP_OFF) = (unsigned32)(_stack_high - CPU_FRAME_SIZE); + *(addr + FP_OFF) = (unsigned32)(_stack_high); #else #error "UNKNOWN CPU!!!" #endif diff --git a/cpukit/score/include/rtems/score/watchdog.h b/cpukit/score/include/rtems/score/watchdog.h index 5c897615f7..c7665bfea2 100644 --- a/cpukit/score/include/rtems/score/watchdog.h +++ b/cpukit/score/include/rtems/score/watchdog.h @@ -100,17 +100,12 @@ typedef struct { } Watchdog_Control; /* - * The following type is used for synchronization purposes + * The following are used for synchronization purposes * during an insert on a watchdog delta chain. - * - * NOTE: Watchdog_Pointer is only used to insure that - * Watchdog_Synchronization_pointer is a pointer - * which is volatile rather than a pointer to a - * volatile block of memory. */ -typedef Watchdog_Control *Watchdog_Pointer; -typedef volatile Watchdog_Pointer Watchdog_Synchronization_pointer; +volatile unsigned32 _Watchdog_Sync_level; +volatile unsigned32 _Watchdog_Sync_count; /* * The following defines the watchdog chains which are managed @@ -120,14 +115,6 @@ typedef volatile Watchdog_Pointer Watchdog_Synchronization_pointer; EXTERN Chain_Control _Watchdog_Ticks_chain; EXTERN Chain_Control _Watchdog_Seconds_chain; -/* - * The following defines the synchronization variable used to - * allow interrupts to be enabled while inserting a watchdog - * on a watchdog chain. - */ - -EXTERN Watchdog_Synchronization_pointer _Watchdog_Sync; - /* * _Watchdog_Handler_initialization * @@ -375,46 +362,6 @@ STATIC INLINE Watchdog_Control *_Watchdog_Last( Chain_Control *header ); -/* - * - * _Watchdog_Get_sync - * - * DESCRIPTION: - * - * This routine returns the current synchronization timer. This - * routine is used so that interrupts can be enabled while a - * watchdog timer is being inserted into a watchdog chain. - */ - -STATIC INLINE Watchdog_Control *_Watchdog_Get_sync( void ); - -/* - * - * _Watchdog_Set_sync - * - * DESCRIPTION: - * - * This routine sets the current synchronization timer. This - * routine is used so that interrupts can be enabled while a - * watchdog timer is being inserted into a watchdog chain. - */ - -STATIC INLINE void _Watchdog_Set_sync( - Watchdog_Control *the_watchdog -); - -/* - * - * _Watchdog_Clear_sync - * - * DESCRIPTION: - * - * This routine will set the watchdog synchronization flag to a - * NULL address indicating synchronization is unnecessary. - */ - -STATIC INLINE void _Watchdog_Clear_sync( void ); - /* * _Watchdog_Adjust * @@ -427,7 +374,7 @@ STATIC INLINE void _Watchdog_Clear_sync( void ); void _Watchdog_Adjust ( Chain_Control *header, Watchdog_Adjust_directions direction, - rtems_interval units + rtems_interval units ); /* diff --git a/cpukit/score/inline/rtems/score/watchdog.inl b/cpukit/score/inline/rtems/score/watchdog.inl index d5d12cbeef..2e7dca0381 100644 --- a/cpukit/score/inline/rtems/score/watchdog.inl +++ b/cpukit/score/inline/rtems/score/watchdog.inl @@ -257,40 +257,5 @@ STATIC INLINE Watchdog_Control *_Watchdog_Last( } -/*PAGE - * - * _Watchdog_Get_sync - * - */ - -STATIC INLINE Watchdog_Control *_Watchdog_Get_sync( void ) -{ - return (Watchdog_Control *) _Watchdog_Sync; -} - -/*PAGE - * - * _Watchdog_Set_sync - * - */ - -STATIC INLINE void _Watchdog_Set_sync( - Watchdog_Control *the_watchdog -) -{ - _Watchdog_Sync = (Watchdog_Synchronization_pointer) the_watchdog; -} - -/*PAGE - * - * _Watchdog_Clear_sync - * - */ - -STATIC INLINE void _Watchdog_Clear_sync( void ) -{ - _Watchdog_Sync = NULL; -} - #endif /* end of include file */ diff --git a/cpukit/score/macros/rtems/score/watchdog.inl b/cpukit/score/macros/rtems/score/watchdog.inl index 1b150d8dab..4e965420ce 100644 --- a/cpukit/score/macros/rtems/score/watchdog.inl +++ b/cpukit/score/macros/rtems/score/watchdog.inl @@ -171,32 +171,5 @@ #define _Watchdog_Last( _header ) \ ((Watchdog_Control *) (_header)->last) -/*PAGE - * - * _Watchdog_Get_sync - * - */ - -#define _Watchdog_Get_sync() \ - ((Watchdog_Control *) _Watchdog_Sync) - -/*PAGE - * - * _Watchdog_Set_sync - * - */ - -#define _Watchdog_Set_sync( _the_watchdog ) \ - _Watchdog_Sync = (Watchdog_Synchronization_pointer) (_the_watchdog) - -/*PAGE - * - * _Watchdog_Clear_sync - * - */ - -#define _Watchdog_Clear_sync() \ - _Watchdog_Sync = NULL; - #endif /* end of include file */ diff --git a/cpukit/score/src/heap.c b/cpukit/score/src/heap.c index 485012ddf7..eb1c5d769e 100644 --- a/cpukit/score/src/heap.c +++ b/cpukit/score/src/heap.c @@ -116,8 +116,13 @@ Heap_Extend_status _Heap_Extend( ) { Heap_Block *the_block; - Heap_Block *next_block; - Heap_Block *previous_block; + + /* + * The overhead was taken from the original heap memory. + */ + + Heap_Block *old_final; + Heap_Block *new_final; /* * There are five possibilities for the location of starting @@ -150,24 +155,27 @@ Heap_Extend_status _Heap_Extend( /* * Currently only case 4 should make it to this point. + * The basic trick is to make the extend area look like a used + * block and free it. */ - *amount_extended = size - HEAP_BLOCK_USED_OVERHEAD; + *amount_extended = size; - previous_block = the_heap->last; + old_final = the_heap->final; + new_final = _Addresses_Add_offset( old_final, size ); + /* SAME AS: _Addresses_Add_offset( starting_address, size-HEAP_OVERHEAD ); */ - the_block = (Heap_Block *) starting_address; - the_block->front_flag = size; - the_block->next = previous_block->next; - the_block->previous = previous_block; + the_heap->final = new_final; - previous_block->next = the_block; - the_heap->last = the_block; + old_final->front_flag = + new_final->back_flag = _Heap_Build_flag( size, HEAP_BLOCK_USED ); + new_final->front_flag = HEAP_DUMMY_FLAG; - next_block = _Heap_Next_block( the_block ); - next_block->back_flag = size; - next_block->front_flag = HEAP_DUMMY_FLAG; - the_heap->final = next_block; + /* + * Must pass in address of "user" area + */ + + _Heap_Free( the_heap, &old_final->next ); return HEAP_EXTEND_SUCCESSFUL; } @@ -392,8 +400,8 @@ void _Heap_Walk( boolean do_dump ) { - Heap_Block *the_block; - Heap_Block *next_block; + Heap_Block *the_block = 0; /* avoid warnings */ + Heap_Block *next_block = 0; /* avoid warnings */ int notdone = 1; /* diff --git a/cpukit/score/src/watchdog.c b/cpukit/score/src/watchdog.c index 7db26c0cd5..3c46f9b535 100644 --- a/cpukit/score/src/watchdog.c +++ b/cpukit/score/src/watchdog.c @@ -30,7 +30,8 @@ void _Watchdog_Handler_initialization( void ) { - _Watchdog_Clear_sync(); + _Watchdog_Sync_count = 0; + _Watchdog_Sync_level = 0; _Chain_Initialize_empty( &_Watchdog_Ticks_chain ); _Chain_Initialize_empty( &_Watchdog_Seconds_chain ); } @@ -56,8 +57,17 @@ Watchdog_States _Watchdog_Remove( switch ( previous_state ) { case WATCHDOG_INACTIVE: break; + + case WATCHDOG_REINSERT: + + /* + * It is not actually on the chain so just change the state and + * the Insert operation we interrupted will be aborted. + */ + the_watchdog->state = WATCHDOG_INACTIVE; + break; + case WATCHDOG_ACTIVE: - case WATCHDOG_REINSERT: case WATCHDOG_REMOVE_IT: the_watchdog->state = WATCHDOG_INACTIVE; @@ -66,8 +76,8 @@ Watchdog_States _Watchdog_Remove( if ( _Watchdog_Next(next_watchdog) ) next_watchdog->delta_interval += the_watchdog->delta_interval; - if ( the_watchdog == _Watchdog_Sync ) - _Watchdog_Sync = _Watchdog_Previous( the_watchdog ); + if ( _Watchdog_Sync_count ) + _Watchdog_Sync_level = _ISR_Nest_level; _Chain_Extract_unprotected( &the_watchdog->Node ); break; @@ -94,7 +104,7 @@ Watchdog_States _Watchdog_Remove( void _Watchdog_Adjust( Chain_Control *header, Watchdog_Adjust_directions direction, - rtems_interval units + rtems_interval units ) { if ( !_Chain_Is_empty( header ) ) { @@ -136,45 +146,66 @@ void _Watchdog_Insert( { ISR_Level level; Watchdog_Control *after; + unsigned32 insert_isr_nest_level; + rtems_interval delta_interval; + + + insert_isr_nest_level = _ISR_Nest_level; + the_watchdog->state = WATCHDOG_REINSERT; - the_watchdog->state = WATCHDOG_REINSERT; - the_watchdog->delta_interval = the_watchdog->initial; + _Watchdog_Sync_count++; +restart: + delta_interval = the_watchdog->initial; _ISR_Disable( level ); for ( after = _Watchdog_First( header ) ; ; - after = _Watchdog_Next( _Watchdog_Get_sync() ) ) { + after = _Watchdog_Next( after ) ) { - if ( the_watchdog->delta_interval == 0 || !_Watchdog_Next( after ) ) + if ( delta_interval == 0 || !_Watchdog_Next( after ) ) break; - if ( the_watchdog->delta_interval < after->delta_interval ) { - after->delta_interval -= the_watchdog->delta_interval; + if ( delta_interval < after->delta_interval ) { + after->delta_interval -= delta_interval; break; } - the_watchdog->delta_interval -= after->delta_interval; - _Watchdog_Set_sync( after ); + delta_interval -= after->delta_interval; /* - * If you experience problems comment out the _ISR_Flash line. Under - * certain circumstances, this flash allows interrupts to execute - * which violate the design assumptions. The critical section - * mechanism used here must be redesigned to address this. + * If you experience problems comment out the _ISR_Flash line. This + * (3.2.0) is the first release with this critical section redesigned. + * Under certain circumstances, the PREVIOUS critical section algorithm + * used around this flash point allows interrupts to execute + * which violated the design assumptions. The critical section + * mechanism used here WAS redesigned to address this. */ _ISR_Flash( level ); + + if ( the_watchdog->state != WATCHDOG_REINSERT ) { + goto exit_insert; + } + + if ( _Watchdog_Sync_level > insert_isr_nest_level ) { + _Watchdog_Sync_level = insert_isr_nest_level; + _ISR_Enable( level ); + goto restart; + } } if ( insert_mode == WATCHDOG_ACTIVATE_NOW ) _Watchdog_Activate( the_watchdog ); - _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node ); + the_watchdog->delta_interval = delta_interval; - _Watchdog_Clear_sync(); + _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node ); - _ISR_Enable( level ); +exit_insert: + _Watchdog_Sync_level = insert_isr_nest_level; + _Watchdog_Sync_count--; + _ISR_Enable( level ); } /*PAGE -- cgit v1.2.3