1/** 2 * \file 3 * \brief morecore() is a sbrk() equivalent. 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2011, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <assert.h> 16#include <k_r_malloc.h> 17#include <stddef.h> 18#include <barrelfish/barrelfish.h> 19#include <barrelfish/core_state.h> 20 21Header *get_malloc_freep(void); 22 23typedef void *(*morecore_alloc_func_t)(size_t bytes, size_t *retbytes); 24typedef void (*morecore_free_func_t)(void *base, size_t bytes); 25 26morecore_alloc_func_t sys_morecore_alloc; 27morecore_free_func_t sys_morecore_free; 28 29/** 30 * \brief sbrk() equivalent. 31 * 32 * This function tries to allocate at least the amount given by 'nu' 33 * in sizeof(::Header) byte units. In some cases, it will allocate 34 * less, if no more memory was available. In any case, It returns a 35 * pointer to the freelist header of the memory region. NULL is 36 * returned when out of memory. 37 * 38 * \param nu Number of memory units (1 unit == sizeof(::Header) bytes) 39 * 40 * \return Pointer to freelist header of new memory region or NULL on out of 41 * memory. 42 */ 43Header *morecore(unsigned nu) 44{ 45 Header *up; 46 size_t nb = nu * sizeof(Header); 47 48 // Allocate requested number of pages and insert freelist header 49 assert(sys_morecore_alloc); 50 up = (Header *)sys_morecore_alloc(nb, &nb); 51 if (up == NULL) { 52 return NULL; 53 } 54 assert(nb % sizeof(Header) == 0); 55 up->s.size = nb / sizeof(Header); 56 57 // Add header to freelist 58 __free_locked((void *)(up + 1)); 59 return get_malloc_freep(); 60} 61 62/** 63 * \brief sbrk() garbage collector. 64 * 65 * Tries to free up pages at the end of the segment, so to shorten the 66 * segment and return memory to the operating system. 67 */ 68void lesscore(void) 69{ 70#if defined(__arm__) || defined(__aarch64__) 71 // Not implemented 72 73#else 74 struct morecore_state *state = get_morecore_state(); 75 genvaddr_t gvaddr = 76 vregion_get_base_addr(&state->mmu_state.vregion) 77 + state->mmu_state.offset; 78 void *eaddr = (void*)vspace_genvaddr_to_lvaddr(gvaddr); 79 80 assert(sys_morecore_free); 81 82 // Deallocate from end of segment 83 Header *prevp = state->header_freep, *p; 84 for(p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { 85 if(p + p->s.size == eaddr) { 86 prevp->s.ptr = p->s.ptr; 87 state->header_freep = prevp; 88 89 // Give back the memory 90 sys_morecore_free(p, p->s.size * sizeof(Header)); 91 break; 92 } 93 94 if (p == state->header_freep) { /* wrapped around free list */ 95 break; 96 } 97 } 98#endif 99} 100