Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:26

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreHeap
0007  *
0008  * @brief This source file contains the implementation of
0009  *   _Heap_Resize_block().
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-1999.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  *  Copyright (c) 2009 embedded brains GmbH & Co. KG
0017  *
0018  * Redistribution and use in source and binary forms, with or without
0019  * modification, are permitted provided that the following conditions
0020  * are met:
0021  * 1. Redistributions of source code must retain the above copyright
0022  *    notice, this list of conditions and the following disclaimer.
0023  * 2. Redistributions in binary form must reproduce the above copyright
0024  *    notice, this list of conditions and the following disclaimer in the
0025  *    documentation and/or other materials provided with the distribution.
0026  *
0027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0037  * POSSIBILITY OF SUCH DAMAGE.
0038  */
0039 
0040 #ifdef HAVE_CONFIG_H
0041 #include "config.h"
0042 #endif
0043 
0044 #include <rtems/score/heapimpl.h>
0045 
0046 static Heap_Resize_status _Heap_Resize_block_checked(
0047   Heap_Control *heap,
0048   Heap_Block *block,
0049   uintptr_t alloc_begin,
0050   uintptr_t new_alloc_size,
0051   uintptr_t *old_size,
0052   uintptr_t *new_size
0053 )
0054 {
0055   Heap_Statistics *const stats = &heap->stats;
0056 
0057   uintptr_t const block_begin = (uintptr_t) block;
0058   uintptr_t block_size = _Heap_Block_size( block );
0059   uintptr_t block_end = block_begin + block_size;
0060 
0061   uintptr_t alloc_size = block_end - alloc_begin + HEAP_ALLOC_BONUS;
0062 
0063   Heap_Block *next_block = _Heap_Block_at( block, block_size );
0064   uintptr_t next_block_size = _Heap_Block_size( next_block );
0065   bool next_block_is_free = _Heap_Is_free( next_block );
0066 
0067   _HAssert( _Heap_Is_block_in_heap( heap, next_block ) );
0068   _HAssert( _Heap_Is_prev_used( next_block ) );
0069 
0070   *old_size = alloc_size;
0071 
0072   if ( next_block_is_free ) {
0073     block_size += next_block_size;
0074     alloc_size += next_block_size;
0075   }
0076 
0077   if ( new_alloc_size > alloc_size ) {
0078     return HEAP_RESIZE_UNSATISFIED;
0079   }
0080 
0081   if ( next_block_is_free ) {
0082     _Heap_Block_set_size( block, block_size );
0083 
0084     _Heap_Free_list_remove( next_block );
0085 
0086     next_block = _Heap_Block_at( block, block_size );
0087     next_block->size_and_flag |= HEAP_PREV_BLOCK_USED;
0088 
0089     /* Statistics */
0090     --stats->free_blocks;
0091     stats->free_size -= next_block_size;
0092   }
0093 
0094   block = _Heap_Block_allocate( heap, block, alloc_begin, new_alloc_size );
0095 
0096   block_size = _Heap_Block_size( block );
0097   next_block = _Heap_Block_at( block, block_size );
0098   *new_size = (uintptr_t) next_block - alloc_begin + HEAP_ALLOC_BONUS;
0099 
0100   /* Statistics */
0101   ++stats->resizes;
0102 
0103   return HEAP_RESIZE_SUCCESSFUL;
0104 }
0105 
0106 Heap_Resize_status _Heap_Resize_block(
0107   Heap_Control *heap,
0108   void *alloc_begin_ptr,
0109   uintptr_t new_alloc_size,
0110   uintptr_t *old_size,
0111   uintptr_t *new_size
0112 )
0113 {
0114   uintptr_t const page_size = heap->page_size;
0115 
0116   uintptr_t const alloc_begin = (uintptr_t) alloc_begin_ptr;
0117 
0118   Heap_Block *const block = _Heap_Block_of_alloc_area( alloc_begin, page_size );
0119 
0120   *old_size = 0;
0121   *new_size = 0;
0122 
0123   if ( _Heap_Is_block_in_heap( heap, block ) ) {
0124     _Heap_Protection_block_check( heap, block );
0125 
0126     /* TODO: Free only the next block if necessary */
0127     _Heap_Protection_free_all_delayed_blocks( heap );
0128 
0129     return _Heap_Resize_block_checked(
0130       heap,
0131       block,
0132       alloc_begin,
0133       new_alloc_size,
0134       old_size,
0135       new_size
0136     );
0137   }
0138   return HEAP_RESIZE_FATAL_ERROR;
0139 }