#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <gpxe/io.h>
#include <gpxe/list.h>
#include <gpxe/init.h>
#include <gpxe/malloc.h>
Go to the source code of this file.
Data Structures | |
| struct | memory_block |
| A free block of memory. More... | |
| struct | autosized_block |
| A block of allocated memory complete with size information. More... | |
Defines | |
| #define | MIN_MEMBLOCK_SIZE ( ( size_t ) ( 1 << ( fls ( sizeof ( struct memory_block ) - 1 ) ) ) ) |
| #define | NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) |
| Address for zero-length memory blocks. | |
| #define | HEAP_SIZE ( 128 * 1024 ) |
| Heap size. | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static | LIST_HEAD (free_blocks) |
| List of free memory blocks. | |
| void * | alloc_memblock (size_t size, size_t align) |
| Allocate a memory block. | |
| void | free_memblock (void *ptr, size_t size) |
| Free a memory block. | |
| void * | realloc (void *old_ptr, size_t new_size) |
| Reallocate memory. | |
| void * | malloc (size_t size) |
| Allocate memory. | |
| void | free (void *ptr) |
| Free memory. | |
| void * | zalloc (size_t size) |
| Allocate cleared memory. | |
| void | mpopulate (void *start, size_t len) |
| Add memory to allocation pool. | |
| static void | init_heap (void) |
| Initialise the heap. | |
| struct init_fn heap_init_fn | __init_fn (INIT_EARLY) |
| Memory allocator initialisation function. | |
Variables | |
| size_t | freemem |
| Total amount of free memory. | |
| static char | heap [HEAP_SIZE] |
| The heap itself. | |
Definition in file malloc.c.
| #define MIN_MEMBLOCK_SIZE ( ( size_t ) ( 1 << ( fls ( sizeof ( struct memory_block ) - 1 ) ) ) ) |
Definition at line 44 of file malloc.c.
Referenced by alloc_memblock(), free_memblock(), and mpopulate().
| #define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) |
Address for zero-length memory blocks.
malloc(0) or realloc(ptr,0) will return the special value NOWHERE. Calling free(NOWHERE) will have no effect.
This is consistent with the ANSI C standards, which state that "either NULL or a pointer suitable to be passed to free()" must be returned in these cases. Using a special non-NULL value means that the caller can take a NULL return value to indicate failure, without first having to check for a requested size of zero.
Code outside of malloc.c do not ever need to refer to the actual value of NOWHERE; this is an internal definition.
Definition at line 70 of file malloc.c.
Referenced by realloc().
| #define HEAP_SIZE ( 128 * 1024 ) |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static LIST_HEAD | ( | free_blocks | ) | [static] |
List of free memory blocks.
Allocate a memory block.
| size | Requested size | |
| align | Physical alignment |
| ptr | Memory block, or NULL |
align must be a power of two. size may not be zero.
Definition at line 100 of file malloc.c.
References DBG, freemem, memory_block::list, list_add, list_del, list_for_each_entry, MIN_MEMBLOCK_SIZE, NULL, memory_block::size, and virt_to_phys().
Referenced by malloc_dma(), mtnic_alloc_aligned(), and realloc().
00100 { 00101 struct memory_block *block; 00102 size_t align_mask; 00103 size_t pre_size; 00104 ssize_t post_size; 00105 struct memory_block *pre; 00106 struct memory_block *post; 00107 00108 /* Round up size to multiple of MIN_MEMBLOCK_SIZE and 00109 * calculate alignment mask. 00110 */ 00111 size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 ); 00112 align_mask = ( align - 1 ) | ( MIN_MEMBLOCK_SIZE - 1 ); 00113 00114 DBG ( "Allocating %#zx (aligned %#zx)\n", size, align ); 00115 00116 /* Search through blocks for the first one with enough space */ 00117 list_for_each_entry ( block, &free_blocks, list ) { 00118 pre_size = ( - virt_to_phys ( block ) ) & align_mask; 00119 post_size = block->size - pre_size - size; 00120 if ( post_size >= 0 ) { 00121 /* Split block into pre-block, block, and 00122 * post-block. After this split, the "pre" 00123 * block is the one currently linked into the 00124 * free list. 00125 */ 00126 pre = block; 00127 block = ( ( ( void * ) pre ) + pre_size ); 00128 post = ( ( ( void * ) block ) + size ); 00129 DBG ( "[%p,%p) -> [%p,%p) + [%p,%p)\n", pre, 00130 ( ( ( void * ) pre ) + pre->size ), pre, block, 00131 post, ( ( ( void * ) pre ) + pre->size ) ); 00132 /* If there is a "post" block, add it in to 00133 * the free list. Leak it if it is too small 00134 * (which can happen only at the very end of 00135 * the heap). 00136 */ 00137 if ( ( size_t ) post_size >= MIN_MEMBLOCK_SIZE ) { 00138 post->size = post_size; 00139 list_add ( &post->list, &pre->list ); 00140 } 00141 /* Shrink "pre" block, leaving the main block 00142 * isolated and no longer part of the free 00143 * list. 00144 */ 00145 pre->size = pre_size; 00146 /* If there is no "pre" block, remove it from 00147 * the list. Also remove it (i.e. leak it) if 00148 * it is too small, which can happen only at 00149 * the very start of the heap. 00150 */ 00151 if ( pre_size < MIN_MEMBLOCK_SIZE ) 00152 list_del ( &pre->list ); 00153 /* Update total free memory */ 00154 freemem -= size; 00155 /* Return allocated block */ 00156 DBG ( "Allocated [%p,%p)\n", block, 00157 ( ( ( void * ) block ) + size ) ); 00158 return block; 00159 } 00160 } 00161 00162 DBG ( "Failed to allocate %#zx (aligned %#zx)\n", size, align ); 00163 return NULL; 00164 }
| void free_memblock | ( | void * | ptr, | |
| size_t | size | |||
| ) |
Free a memory block.
| ptr | Memory allocated by alloc_memblock(), or NULL | |
| size | Size of the memory |
ptr is NULL, no action is taken.
Definition at line 174 of file malloc.c.
References DBG, freemem, memory_block::list, list_add_tail, list_del, list_for_each_entry, MIN_MEMBLOCK_SIZE, and memory_block::size.
Referenced by free_dma(), mpopulate(), mtnic_alloc_cq(), mtnic_alloc_resources(), mtnic_alloc_ring(), mtnic_close(), mtnic_disable(), mtnic_init_card(), mtnic_open(), and realloc().
00174 { 00175 struct memory_block *freeing; 00176 struct memory_block *block; 00177 ssize_t gap_before; 00178 ssize_t gap_after = -1; 00179 00180 /* Allow for ptr==NULL */ 00181 if ( ! ptr ) 00182 return; 00183 00184 /* Round up size to match actual size that alloc_memblock() 00185 * would have used. 00186 */ 00187 size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 ); 00188 freeing = ptr; 00189 freeing->size = size; 00190 DBG ( "Freeing [%p,%p)\n", freeing, ( ( ( void * ) freeing ) + size )); 00191 00192 /* Insert/merge into free list */ 00193 list_for_each_entry ( block, &free_blocks, list ) { 00194 /* Calculate gaps before and after the "freeing" block */ 00195 gap_before = ( ( ( void * ) freeing ) - 00196 ( ( ( void * ) block ) + block->size ) ); 00197 gap_after = ( ( ( void * ) block ) - 00198 ( ( ( void * ) freeing ) + freeing->size ) ); 00199 /* Merge with immediately preceding block, if possible */ 00200 if ( gap_before == 0 ) { 00201 DBG ( "[%p,%p) + [%p,%p) -> [%p,%p)\n", block, 00202 ( ( ( void * ) block ) + block->size ), freeing, 00203 ( ( ( void * ) freeing ) + freeing->size ),block, 00204 ( ( ( void * ) freeing ) + freeing->size ) ); 00205 block->size += size; 00206 list_del ( &block->list ); 00207 freeing = block; 00208 } 00209 /* Stop processing as soon as we reach a following block */ 00210 if ( gap_after >= 0 ) 00211 break; 00212 } 00213 00214 /* Insert before the immediately following block. If 00215 * possible, merge the following block into the "freeing" 00216 * block. 00217 */ 00218 DBG ( "[%p,%p)\n", freeing, ( ( ( void * ) freeing ) + freeing->size)); 00219 list_add_tail ( &freeing->list, &block->list ); 00220 if ( gap_after == 0 ) { 00221 DBG ( "[%p,%p) + [%p,%p) -> [%p,%p)\n", freeing, 00222 ( ( ( void * ) freeing ) + freeing->size ), block, 00223 ( ( ( void * ) block ) + block->size ), freeing, 00224 ( ( ( void * ) block ) + block->size ) ); 00225 freeing->size += block->size; 00226 list_del ( &block->list ); 00227 } 00228 00229 /* Update free memory counter */ 00230 freemem += size; 00231 }
| void* realloc | ( | void * | old_ptr, | |
| size_t | new_size | |||
| ) |
Reallocate memory.
| old_ptr | Memory previously allocated by malloc(), or NULL | |
| new_size | Requested size |
| new_ptr | Allocated memory, or NULL |
new_ptr will be aligned to at least a multiple of sizeof(void*). If old_ptr is non-NULL, then the contents of the newly allocated memory will be the same as the contents of the previously allocated memory, up to the minimum of the old and new sizes. The old memory will be freed.If allocation fails the previously allocated block is left untouched and NULL is returned.
Calling realloc() with a new size of zero is a valid way to free a memory block.
Definition at line 253 of file malloc.c.
References alloc_memblock(), container_of, autosized_block::data, free_memblock(), memcpy, NOWHERE, NULL, offsetof, and autosized_block::size.
Referenced by bitmap_resize(), free(), line_buffer(), malloc(), more_comps(), and resize_dhcp_option().
00253 { 00254 struct autosized_block *old_block; 00255 struct autosized_block *new_block; 00256 size_t old_total_size; 00257 size_t new_total_size; 00258 size_t old_size; 00259 void *new_ptr = NOWHERE; 00260 00261 /* Allocate new memory if necessary. If allocation fails, 00262 * return without touching the old block. 00263 */ 00264 if ( new_size ) { 00265 new_total_size = ( new_size + 00266 offsetof ( struct autosized_block, data ) ); 00267 new_block = alloc_memblock ( new_total_size, 1 ); 00268 if ( ! new_block ) 00269 return NULL; 00270 new_block->size = new_total_size; 00271 new_ptr = &new_block->data; 00272 } 00273 00274 /* Copy across relevant part of the old data region (if any), 00275 * then free it. Note that at this point either (a) new_ptr 00276 * is valid, or (b) new_size is 0; either way, the memcpy() is 00277 * valid. 00278 */ 00279 if ( old_ptr && ( old_ptr != NOWHERE ) ) { 00280 old_block = container_of ( old_ptr, struct autosized_block, 00281 data ); 00282 old_total_size = old_block->size; 00283 old_size = ( old_total_size - 00284 offsetof ( struct autosized_block, data ) ); 00285 memcpy ( new_ptr, old_ptr, 00286 ( ( old_size < new_size ) ? old_size : new_size ) ); 00287 free_memblock ( old_block, old_total_size ); 00288 } 00289 00290 return new_ptr; 00291 }
| void* malloc | ( | size_t | size | ) |
Allocate memory.
| size | Requested size |
| ptr | Memory, or NULL |
ptr will be aligned to at least a multiple of sizeof(void*).
Definition at line 302 of file malloc.c.
References NULL, and realloc().
Referenced by add_ipv4_miniroute(), add_ipv6_miniroute(), add_tls(), aes_unwrap(), aes_wrap(), alloc(), apply_iscsi_string_setting(), ath5k_hw_rfregs_init(), bi_mod_power(), chap_init(), derwin(), dupwin(), eisabus_probe(), fetch_string_setting_copy(), ipv4_reassemble(), isabus_probe(), isapnpbus_probe(), iscsi_rx_buffered_data(), mcabus_probe(), net80211_probe_start(), net80211_register(), newwin(), pcibus_probe(), register_nvo(), RSA_decrypt(), rtl_open(), strndup(), subwin(), t509bus_probe(), tls_assemble_block(), tls_assemble_stream(), tls_new_ciphertext(), tls_newdata_process_header(), tls_set_cipher(), vasprintf(), wpa_make_rsn_ie(), wpa_start(), x509_rsa_public_key(), and zalloc().
| void free | ( | void * | ptr | ) |
Free memory.
| ptr | Memory allocated by malloc(), or NULL |
If ptr is NULL, no action is taken.
Definition at line 316 of file malloc.c.
References realloc().
Referenced by aes_unwrap(), aes_wrap(), aoe_free(), aoeboot(), apply_iscsi_string_setting(), arbel_create_cq(), arbel_create_qp(), arbel_destroy_cq(), arbel_destroy_qp(), arbel_probe(), arbel_remove(), ath5k_desc_free(), ath5k_eeprom_free_pcal_info(), ath5k_hw_attach(), ath5k_hw_detach(), ath5k_probe(), ath5k_remove(), atl1e_free_ring_resources(), bi_mod_power(), bi_terminate(), bitmap_free(), chap_finish(), del_ipv4_miniroute(), del_ipv6_miniroute(), delwin(), dhcp_free(), dns_resolv(), downloader_free(), efi_snp_driver_start(), efi_snp_driver_stop(), eisabus_probe(), eisabus_remove(), empty_line_buffer(), expand_command(), free_fragbuf(), free_image(), free_netdev(), free_tls(), ftp_free(), generic_settings_clear(), generic_settings_store(), hermon_create_cq(), hermon_create_qp(), hermon_destroy_cq(), hermon_destroy_qp(), hermon_probe(), hermon_remove(), http_free(), ib_create_conn(), ib_create_cq(), ib_create_mi(), ib_create_path(), ib_create_qp(), ib_destroy_conn(), ib_destroy_cq(), ib_destroy_madx(), ib_destroy_mi(), ib_destroy_path(), ib_destroy_qp(), ib_mcast_attach(), ib_mcast_detach(), ib_srpboot(), image_set_cmdline(), isabus_probe(), isabus_remove(), isapnpbus_probe(), isapnpbus_remove(), iscsi_free(), iscsi_handle_targetaddress_value(), iscsi_rx_buffered_data_done(), iscsiboot(), linda_create_send_wq(), linda_destroy_send_wq(), mcabus_probe(), mcabus_remove(), mtnic_disable(), mtnic_probe(), net80211_autoassociate(), net80211_free(), net80211_free_wlan(), net80211_free_wlanlist(), net80211_mgmt_dequeue(), net80211_netdev_close(), net80211_prepare_assoc(), net80211_probe_finish_all(), net80211_probe_finish_best(), net80211_step_associate(), pcibus_probe(), pcibus_remove(), posix_file_free(), pxe_menu_boot(), rc80211_free(), ref_put(), register_nvo(), resolve_uri(), RSA_decrypt(), RSA_free(), rtl818x_probe(), rtl_close(), sec80211_install(), shell(), sis190_free_phy(), skge_free(), skge_probe(), skge_remove(), sky2_free_rings(), sky2_probe(), sky2_remove(), slam_free(), system(), t509bus_probe(), t509bus_remove(), tftp_free(), tls_clear_cipher(), tls_new_ciphertext(), tls_newdata_process_data(), tls_send_plaintext(), undipci_probe(), undipci_remove(), undirom_probe(), unregister_nvo(), vxge_hw_device_terminate(), wpa_stop(), and x509_free_rsa_public_key().
00316 { 00317 realloc ( ptr, 0 ); 00318 }
| void* zalloc | ( | size_t | size | ) |
Allocate cleared memory.
| size | Requested size |
| ptr | Allocated memory |
This function name is non-standard, but pretty intuitive. zalloc(size) is always equivalent to calloc(1,size)
Definition at line 331 of file malloc.c.
References autosized_block::data, malloc(), and memset().
Referenced by alloc_ibdev(), alloc_image(), alloc_netdev(), aoe_attach(), aoeboot(), arbel_create_cq(), arbel_create_qp(), arbel_probe(), ath5k_hw_attach(), ath5k_probe(), atl1e_setup_ring_resources(), autovivify_child_settings(), calloc(), create_downloader(), dhcp_deliver_iob(), dns_resolv(), efi_snp_driver_start(), ftp_open(), generic_settings_store(), hermon_create_cq(), hermon_create_qp(), hermon_probe(), http_open_filter(), hw_open(), ib_cmrc_open(), ib_create_conn(), ib_create_cq(), ib_create_madx(), ib_create_mi(), ib_create_path(), ib_create_qp(), ib_mcast_attach(), ib_srpboot(), iscsi_attach(), iscsiboot(), linda_create_send_wq(), mtnic_probe(), net80211_handle_mgmt(), net80211_prepare_assoc(), net80211_probe_start(), net80211_probe_step(), net80211_step_associate(), numeric_resolv(), open(), parse_uri(), pxe_menu_parse(), rc80211_init(), resolv(), rtl818x_probe(), sec80211_install(), sis190_mii_probe(), skge_probe(), skge_ring_alloc(), sky2_probe(), sky2_up(), slam_open(), srp_attach(), start_dhcp(), start_pxebs(), store_cached_dhcpack(), tcp_open(), tftp_core_open(), udp_open_common(), undipci_probe(), undirom_probe(), vxge_hw_device_initialize(), and xfer_open_named_socket().
00331 { 00332 void *data; 00333 00334 data = malloc ( size ); 00335 if ( data ) 00336 memset ( data, 0, size ); 00337 return data; 00338 }
| void mpopulate | ( | void * | start, | |
| size_t | len | |||
| ) |
Add memory to allocation pool.
| start | Start address | |
| end | End address |
start must be aligned to at least a multiple of sizeof(void*).
Definition at line 351 of file malloc.c.
References free_memblock(), and MIN_MEMBLOCK_SIZE.
Referenced by init_heap().
00351 { 00352 /* Prevent free_memblock() from rounding up len beyond the end 00353 * of what we were actually given... 00354 */ 00355 free_memblock ( start, ( len & ~( MIN_MEMBLOCK_SIZE - 1 ) ) ); 00356 }
| static void init_heap | ( | void | ) | [static] |
| struct init_fn heap_init_fn __init_fn | ( | INIT_EARLY | ) | [read] |
Memory allocator initialisation function.
Total amount of free memory.
Definition at line 76 of file malloc.c.
Referenced by alloc_memblock(), free_memblock(), and tcp_xmit().
char heap[HEAP_SIZE] [static] |
1.5.7.1