From 93b4e6ef7ea97190a1d542191e78e287a3b540f4 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 2 Nov 1999 21:05:17 +0000 Subject: Split Heap and Time of Day Handlers. --- cpukit/score/src/heapextend.c | 113 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 cpukit/score/src/heapextend.c (limited to 'cpukit/score/src/heapextend.c') diff --git a/cpukit/score/src/heapextend.c b/cpukit/score/src/heapextend.c new file mode 100644 index 0000000000..38b74e66e2 --- /dev/null +++ b/cpukit/score/src/heapextend.c @@ -0,0 +1,113 @@ +/* + * Heap Handler + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include + +/*PAGE + * + * _Heap_Extend + * + * This routine grows the_heap memory area using the size bytes which + * begin at starting_address. + * + * Input parameters: + * the_heap - pointer to heap header. + * starting_address - pointer to the memory area. + * size - size in bytes of the memory block to allocate. + * + * Output parameters: + * *amount_extended - amount of memory added to the_heap + */ + +Heap_Extend_status _Heap_Extend( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 *amount_extended +) +{ + Heap_Block *the_block; + unsigned32 *p; + + /* + * 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 + * address: + * + * 1. non-contiguous lower address (NOT SUPPORTED) + * 2. contiguous lower address (NOT SUPPORTED) + * 3. in the heap (ERROR) + * 4. contiguous higher address (SUPPORTED) + * 5. non-contiguous higher address (NOT SUPPORTED) + * + * As noted, this code only supports (4). + */ + + if ( starting_address >= (void *) the_heap->start && /* case 3 */ + starting_address <= (void *) the_heap->final + ) + return HEAP_EXTEND_ERROR; + + if ( starting_address < (void *) the_heap->start ) { /* cases 1 and 2 */ + + return HEAP_EXTEND_NOT_IMPLEMENTED; /* cases 1 and 2 */ + + } else { /* cases 4 and 5 */ + + the_block = (Heap_Block *) + _Addresses_Subtract_offset( starting_address, HEAP_OVERHEAD ); + if ( the_block != the_heap->final ) + return HEAP_EXTEND_NOT_IMPLEMENTED; /* case 5 */ + } + + /* + * 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; + + old_final = the_heap->final; + new_final = _Addresses_Add_offset( old_final, size ); + /* SAME AS: _Addresses_Add_offset( starting_address, size-HEAP_OVERHEAD ); */ + + the_heap->final = new_final; + + old_final->front_flag = + new_final->back_flag = _Heap_Build_flag( size, HEAP_BLOCK_USED ); + new_final->front_flag = HEAP_DUMMY_FLAG; + + /* + * Must pass in address of "user" area + * So add in the offset field. + */ + + p = (unsigned32 *) &old_final->next; + *p = sizeof(unsigned32); + p++; + _Heap_Free( the_heap, p ); + + return HEAP_EXTEND_SUCCESSFUL; +} + -- cgit v1.2.3