static void test_heap_size_with_overhead(void) { uintptr_t s; puts( "_Heap_Size_with_overhead" ); s = _Heap_Size_with_overhead(0, 0, 0); rtems_test_assert(s == HEAP_BLOCK_HEADER_SIZE + CPU_ALIGNMENT - 1); s = _Heap_Size_with_overhead(CPU_ALIGNMENT, 0, 0); rtems_test_assert(s == HEAP_BLOCK_HEADER_SIZE + CPU_ALIGNMENT - 1); s = _Heap_Size_with_overhead(CPU_ALIGNMENT, 0, 2 * CPU_ALIGNMENT); rtems_test_assert(s == HEAP_BLOCK_HEADER_SIZE + 2 * CPU_ALIGNMENT - 1); s = _Heap_Size_with_overhead(CPU_ALIGNMENT, 123, 0); rtems_test_assert(s == HEAP_BLOCK_HEADER_SIZE + CPU_ALIGNMENT - 1 + 123); }
void _Workspace_Handler_initialization( Heap_Area *areas, size_t area_count, Heap_Initialization_or_extend_handler extend ) { Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize; uintptr_t remaining = rtems_configuration_get_work_space_size(); bool do_zero = rtems_configuration_get_do_zero_of_workspace(); bool unified = rtems_configuration_get_unified_work_area(); uintptr_t page_size = CPU_HEAP_ALIGNMENT; uintptr_t overhead = _Heap_Area_overhead( page_size ); uintptr_t tls_size = _TLS_Get_size(); size_t i; /* * In case we have a non-zero TLS size, then we need a TLS area for each * thread. These areas are allocated from the workspace. Ensure that the * workspace is large enough to fulfill all requests known at configuration * time (so excluding the unlimited option). It is not possible to estimate * the TLS size in the configuration at compile-time. The TLS size is * determined at application link-time. */ if ( tls_size > 0 ) { uintptr_t tls_align = _TLS_Heap_align_up( (uintptr_t) _TLS_Alignment ); uintptr_t tls_alloc = _TLS_Get_allocation_size( tls_size, tls_align ); /* * Memory allocated with an alignment constraint is allocated from the end * of a free block. The last allocation may need one free block of minimum * size. */ remaining += _Heap_Min_block_size( page_size ); remaining += _Get_maximum_thread_count() * _Heap_Size_with_overhead( page_size, tls_alloc, tls_align ); } for (i = 0; i < area_count; ++i) { Heap_Area *area = &areas [i]; if ( do_zero ) { memset( area->begin, 0, area->size ); } if ( area->size > overhead ) { uintptr_t space_available; uintptr_t size; if ( unified ) { size = area->size; } else { if ( remaining > 0 ) { size = remaining < area->size - overhead ? remaining + overhead : area->size; } else { size = 0; } } space_available = (*init_or_extend)( &_Workspace_Area, area->begin, size, page_size ); area->begin = (char *) area->begin + size; area->size -= size; if ( space_available < remaining ) { remaining -= space_available; } else { remaining = 0; } init_or_extend = extend; } } if ( remaining > 0 ) { _Internal_error( INTERNAL_ERROR_TOO_LITTLE_WORKSPACE ); } _Heap_Protection_set_delayed_free_fraction( &_Workspace_Area, 1 ); }